diff --git a/.changeset/chilled-brooms-grow.md b/.changeset/chilled-brooms-grow.md new file mode 100644 index 00000000000..73d033b8b38 --- /dev/null +++ b/.changeset/chilled-brooms-grow.md @@ -0,0 +1,7 @@ +--- +"@primer/react": patch +--- + +`MarkdownEditor` is now SSR-compatible. + +Warning: In this new implementation, `MarkdownEditor.Toolbar`, `MarkdownEditor.Actions`, and `MarkdownEditor.Label` must be direct children of `MarkdownEditor`. diff --git a/.changeset/lemon-berries-run.md b/.changeset/lemon-berries-run.md new file mode 100644 index 00000000000..1e7bfe65ad4 --- /dev/null +++ b/.changeset/lemon-berries-run.md @@ -0,0 +1,7 @@ +--- +"@primer/react": patch +--- + +`ActionList` and `NavList` are now SSR-compatible. + +Warning: In this new implementation, `ActionList.LeadingVisual`, `ActionList.TrailingVisual,` and `ActionList.Description` must be direct children of `ActionList`. The same applies to `NavList`. diff --git a/.changeset/wicked-knives-sparkle.md b/.changeset/wicked-knives-sparkle.md new file mode 100644 index 00000000000..760da1a2b88 --- /dev/null +++ b/.changeset/wicked-knives-sparkle.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +Bug fix: `ButtonGroup` borders show incorrectly on hover diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-colorblind-linux.png index 64932a7e6f7..1b03a407f82 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-colorblind-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-dimmed-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-dimmed-linux.png index 1b05ebd875e..2b2eeb2a072 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-dimmed-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-high-contrast-linux.png index 95fa59bdd8b..3963ab15c0f 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-high-contrast-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-linux.png index 64932a7e6f7..1b03a407f82 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-tritanopia-linux.png index 64932a7e6f7..1b03a407f82 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-tritanopia-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-colorblind-linux.png index 9ee65793293..a2fd494b318 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-colorblind-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-high-contrast-linux.png index 9a6174ae0df..95c5fd8b16c 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-high-contrast-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-linux.png index b3e3f5d2d29..593e7070bde 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-tritanopia-linux.png index 9ee65793293..a2fd494b318 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-tritanopia-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Icon-Buttons-light-tritanopia-linux.png differ diff --git a/generated/components.json b/generated/components.json index 063d1273e37..653506bd7fc 100644 --- a/generated/components.json +++ b/generated/components.json @@ -3120,7 +3120,12 @@ "name": "Portal", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-portal--default", + "code": "() => (\n <>\n Root position\n \n Outer container\n \n Inner container\n \n Portaled content rendered at <BaseStyles> root.\n \n \n \n \n)" + } + ], "props": [ { "name": "onMount", diff --git a/src/ActionList/Description.tsx b/src/ActionList/Description.tsx index 63b89d4356b..4027ec22f58 100644 --- a/src/ActionList/Description.tsx +++ b/src/ActionList/Description.tsx @@ -1,8 +1,8 @@ import React from 'react' import Box from '../Box' -import {SxProp, merge} from '../sx' import Truncate from '../Truncate' -import {Slot, ItemContext} from './shared' +import {SxProp, merge} from '../sx' +import {ItemContext} from './shared' export type ActionListDescriptionProps = { /** @@ -28,29 +28,25 @@ export const Description: React.FC - {({blockDescriptionId, inlineDescriptionId, disabled}: ItemContext) => - variant === 'block' ? ( - - {props.children} - - ) : ( - - {props.children} - - ) - } - + const {blockDescriptionId, inlineDescriptionId, disabled} = React.useContext(ItemContext) + + return variant === 'block' ? ( + + {props.children} + + ) : ( + + {props.children} + ) } diff --git a/src/ActionList/Item.tsx b/src/ActionList/Item.tsx index ca479ff450f..d594cc66f66 100644 --- a/src/ActionList/Item.tsx +++ b/src/ActionList/Item.tsx @@ -1,16 +1,19 @@ -import {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' import React from 'react' import styled from 'styled-components' import Box, {BoxProps} from '../Box' +import {useId} from '../hooks/useId' +import {useSlots} from '../hooks/useSlots' import sx, {BetterSystemStyleObject, merge, SxProp} from '../sx' import {useTheme} from '../ThemeProvider' -import {useId} from '../hooks/useId' +import {defaultSxProp} from '../utils/defaultSxProp' +import {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' import {ActionListContainerContext} from './ActionListContainerContext' +import {Description} from './Description' import {ActionListGroupProps, GroupContext} from './Group' import {ActionListProps, ListContext} from './List' import {Selection} from './Selection' -import {ActionListItemProps, Slots, TEXT_ROW_HEIGHT, getVariantStyles} from './shared' -import {defaultSxProp} from '../utils/defaultSxProp' +import {ActionListItemProps, getVariantStyles, ItemContext, TEXT_ROW_HEIGHT} from './shared' +import {LeadingVisual, TrailingVisual} from './Visuals' const LiBox = styled.li(sx) @@ -30,6 +33,11 @@ export const Item = React.forwardRef( }, forwardedRef, ): JSX.Element => { + const [slots, childrenWithoutSlots] = useSlots(props.children, { + leadingVisual: LeadingVisual, + trailingVisual: TrailingVisual, + description: Description, + }) const {variant: listVariant, showDividers, selectionVariant: listSelectionVariant} = React.useContext(ListContext) const {selectionVariant: groupSelectionVariant} = React.useContext(GroupContext) const {container, afterSelect, selectionAttribute} = React.useContext(ActionListContainerContext) @@ -169,66 +177,57 @@ export const Item = React.forwardRef( const ItemWrapper = _PrivateItemWrapper || React.Fragment + const menuItemProps = { + onClick: clickHandler, + onKeyPress: keyPressHandler, + 'aria-disabled': disabled ? true : undefined, + tabIndex: disabled ? undefined : 0, + 'aria-labelledby': `${labelId} ${ + slots.description && slots.description.props.variant !== 'block' ? inlineDescriptionId : '' + }`, + 'aria-describedby': slots.description?.props.variant === 'block' ? blockDescriptionId : undefined, + ...(selectionAttribute && {[selectionAttribute]: selected}), + role: role || itemRole, + } + + const containerProps = _PrivateItemWrapper ? {role: role || itemRole ? 'none' : undefined} : menuItemProps + + const wrapperProps = _PrivateItemWrapper ? menuItemProps : {} + return ( - - {slots => { - const menuItemProps = { - onClick: clickHandler, - onKeyPress: keyPressHandler, - 'aria-disabled': disabled ? true : undefined, - tabIndex: disabled ? undefined : 0, - 'aria-labelledby': `${labelId} ${slots.InlineDescription ? inlineDescriptionId : ''}`, - 'aria-describedby': slots.BlockDescription ? blockDescriptionId : undefined, - ...(selectionAttribute && {[selectionAttribute]: selected}), - role: role || itemRole, - } - const containerProps = _PrivateItemWrapper - ? { - role: role || itemRole ? 'none' : undefined, - } - : menuItemProps - const wrapperProps = _PrivateItemWrapper ? menuItemProps : {} - - return ( - (styles, sxProp)} - {...containerProps} - {...props} + + (styles, sxProp)} {...containerProps} {...props}> + + + {slots.leadingVisual} + - - - {slots.LeadingVisual} - + - - - - {props.children} - - {slots.InlineDescription} - - {slots.TrailingVisual} - - {slots.BlockDescription} - - - - ) - }} - + + {childrenWithoutSlots} + + {slots.description?.props.variant !== 'block' ? slots.description : null} + + {slots.trailingVisual} + + {slots.description?.props.variant === 'block' ? slots.description : null} + + + + ) }, ) as PolymorphicForwardRefComponent<'li', ActionListItemProps> diff --git a/src/ActionList/Visuals.tsx b/src/ActionList/Visuals.tsx index 5ca38b66943..4a290b20f3e 100644 --- a/src/ActionList/Visuals.tsx +++ b/src/ActionList/Visuals.tsx @@ -1,8 +1,8 @@ import React from 'react' import Box from '../Box' -import {SxProp, merge} from '../sx' import {get} from '../constants' -import {getVariantStyles, Slot, ItemContext, TEXT_ROW_HEIGHT} from './shared' +import {SxProp, merge} from '../sx' +import {ItemContext, TEXT_ROW_HEIGHT, getVariantStyles} from './shared' type VisualProps = SxProp & React.HTMLAttributes @@ -30,48 +30,42 @@ export const LeadingVisualContainer: React.FC> = ({sx = {}, ...props}) => { + const {variant, disabled} = React.useContext(ItemContext) return ( - - {({variant, disabled}: ItemContext) => ( - - {props.children} - + + {...props} + > + {props.children} + ) } export type ActionListTrailingVisualProps = VisualProps export const TrailingVisual: React.FC> = ({sx = {}, ...props}) => { + const {variant, disabled} = React.useContext(ItemContext) return ( - - {({variant, disabled}: ItemContext) => ( - - {props.children} - + + {...props} + > + {props.children} + ) } diff --git a/src/ActionList/shared.ts b/src/ActionList/shared.ts index 6e281c46b9e..10b79112915 100644 --- a/src/ActionList/shared.ts +++ b/src/ActionList/shared.ts @@ -1,6 +1,5 @@ import React from 'react' import {SxProp} from '../sx' -import createSlots from '../utils/create-slots' import {AriaRole} from '../utils/types' export type ActionListItemProps = { @@ -56,10 +55,12 @@ type MenuItemProps = { } export type ItemContext = Pick & { - inlineDescriptionId: string - blockDescriptionId: string + inlineDescriptionId?: string + blockDescriptionId?: string } +export const ItemContext = React.createContext({}) + export const getVariantStyles = ( variant: ActionListItemProps['variant'], disabled: ActionListItemProps['disabled'], @@ -90,6 +91,4 @@ export const getVariantStyles = ( } } -export const {Slots, Slot} = createSlots(['LeadingVisual', 'InlineDescription', 'BlockDescription', 'TrailingVisual']) - export const TEXT_ROW_HEIGHT = '20px' // custom value off the scale diff --git a/src/ButtonGroup/ButtonGroup.tsx b/src/ButtonGroup/ButtonGroup.tsx index 93762b8574a..9e49b669aca 100644 --- a/src/ButtonGroup/ButtonGroup.tsx +++ b/src/ButtonGroup/ButtonGroup.tsx @@ -9,29 +9,23 @@ const ButtonGroup = styled.div` isolation: isolate; && > * { + margin-inline-end: -1px; position: relative; - border-right-width: 0; border-radius: 0; :first-child { border-top-left-radius: ${get('radii.2')}; border-bottom-left-radius: ${get('radii.2')}; - margin-right: 0; - } - - :not(:first-child) { - margin-left: 0; - margin-right: 0; } :last-child { - border-right-width: 1px; border-top-right-radius: ${get('radii.2')}; border-bottom-right-radius: ${get('radii.2')}; } :focus, - :active { + :active, + :hover { z-index: 1; } } diff --git a/src/NavList/__snapshots__/NavList.test.tsx.snap b/src/NavList/__snapshots__/NavList.test.tsx.snap index 20a4fc9ba53..d4a6444a291 100644 --- a/src/NavList/__snapshots__/NavList.test.tsx.snap +++ b/src/NavList/__snapshots__/NavList.test.tsx.snap @@ -1278,12 +1278,6 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t list-style: none; } -.c9 { - padding: 0; - margin: 0; - display: none; -} - .c5 { display: -webkit-box; display: -webkit-flex; @@ -1295,6 +1289,12 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t flex-grow: 1; } +.c9 { + padding: 0; + margin: 0; + display: none; +} + .c7 { height: 20px; -webkit-flex-shrink: 0; diff --git a/src/stories/Portal.stories.tsx b/src/Portal/Portal.features.stories.tsx similarity index 78% rename from src/stories/Portal.stories.tsx rename to src/Portal/Portal.features.stories.tsx index e0d0df71c2f..45bc5a969cf 100644 --- a/src/stories/Portal.stories.tsx +++ b/src/Portal/Portal.features.stories.tsx @@ -1,39 +1,12 @@ import React from 'react' -import {Meta} from '@storybook/react' - -import {BaseStyles, Box, ThemeProvider} from '..' -import Portal, {registerPortalRoot} from '../Portal' +import {ComponentMeta} from '@storybook/react' +import Box from '../Box' +import {Portal, registerPortalRoot} from './Portal' export default { - title: 'Behaviors/Portal', + title: 'Behaviors/Portal/Features', component: Portal, - decorators: [ - Story => { - return ( - - - - - - ) - }, - ], -} as Meta - -export const DefaultPortal = () => ( - <> - Root position - - Outer container - - Inner container - - Portaled content rendered at <BaseStyles> root. - - - - -) +} as ComponentMeta export const CustomPortalRootById = () => ( <> diff --git a/src/Portal/Portal.stories.tsx b/src/Portal/Portal.stories.tsx new file mode 100644 index 00000000000..6755d7e28da --- /dev/null +++ b/src/Portal/Portal.stories.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import {ComponentMeta} from '@storybook/react' + +import {Box} from '..' +import {Portal} from './Portal' + +export default { + title: 'Behaviors/Portal', + component: Portal, +} as ComponentMeta + +export const Default = () => ( + <> + Root position + + Outer container + + Inner container + + Portaled content rendered at <BaseStyles> root. + + + + +) diff --git a/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap index f7e8cc7944f..9c106f86e5a 100644 --- a/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap +++ b/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap @@ -293,30 +293,24 @@ exports[`ButtonGroup renders consistently 1`] = ` } .c0.c0 > * { + margin-inline-end: -1px; position: relative; - border-right-width: 0; border-radius: 0; } .c0.c0 > *:first-child { border-top-left-radius: 6px; border-bottom-left-radius: 6px; - margin-right: 0; -} - -.c0.c0 > *:not(:first-child) { - margin-left: 0; - margin-right: 0; } .c0.c0 > *:last-child { - border-right-width: 1px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; } .c0.c0 > *:focus, -.c0.c0 > *:active { +.c0.c0 > *:active, +.c0.c0 > *:hover { z-index: 1; } diff --git a/src/drafts/MarkdownEditor/Actions.tsx b/src/drafts/MarkdownEditor/Actions.tsx index 5a0c8f3f97d..25055e623b9 100644 --- a/src/drafts/MarkdownEditor/Actions.tsx +++ b/src/drafts/MarkdownEditor/Actions.tsx @@ -1,11 +1,8 @@ import React, {forwardRef, useContext} from 'react' import {Button, ButtonProps} from '../../Button' -import {MarkdownEditorSlot} from './MarkdownEditor' import {MarkdownEditorContext} from './_MarkdownEditorContext' -export const Actions = ({children}: {children?: React.ReactNode}) => ( - {children} -) +export const Actions = ({children}: {children?: React.ReactNode}) => <>{children} Actions.displayName = 'MarkdownEditor.Actions' export const ActionButton = forwardRef((props, ref) => { diff --git a/src/drafts/MarkdownEditor/Label.tsx b/src/drafts/MarkdownEditor/Label.tsx index 5cc36a55485..bf55398b86e 100644 --- a/src/drafts/MarkdownEditor/Label.tsx +++ b/src/drafts/MarkdownEditor/Label.tsx @@ -1,7 +1,6 @@ import React, {FC, useContext} from 'react' -import {SxProp} from '../../sx' import InputLabel from '../../_InputLabel' -import {MarkdownEditorSlot} from './MarkdownEditor' +import {SxProp} from '../../sx' import {MarkdownEditorContext} from './_MarkdownEditorContext' type LabelProps = SxProp & { @@ -20,8 +19,4 @@ const Legend: FC = ({sx, ...props}) => { } Legend.displayName = 'MarkdownEditor.Label' -export const Label: FC = props => ( - - - -) +export const Label: FC = props => diff --git a/src/drafts/MarkdownEditor/MarkdownEditor.tsx b/src/drafts/MarkdownEditor/MarkdownEditor.tsx index f077d1a1cb3..e126270f716 100644 --- a/src/drafts/MarkdownEditor/MarkdownEditor.tsx +++ b/src/drafts/MarkdownEditor/MarkdownEditor.tsx @@ -9,31 +9,33 @@ import React, { useState, } from 'react' import Box from '../../Box' -import {FileType} from '../hooks/useUnifiedFileSelect' +import VisuallyHidden from '../../_VisuallyHidden' import {useId} from '../../hooks/useId' -import {useIgnoreKeyboardActionsWhileComposing} from '../hooks/useIgnoreKeyboardActionsWhileComposing' import {useResizeObserver} from '../../hooks/useResizeObserver' -import {useSyntheticChange} from '../hooks/useSyntheticChange' -import MarkdownViewer from '../MarkdownViewer' +import {useSlots} from '../../hooks/useSlots' import {SxProp} from '../../sx' -import createSlots from '../../utils/create-slots' -import VisuallyHidden from '../../_VisuallyHidden' +import MarkdownViewer from '../MarkdownViewer' +import {useIgnoreKeyboardActionsWhileComposing} from '../hooks/useIgnoreKeyboardActionsWhileComposing' +import {useSafeAsyncCallback} from '../hooks/useSafeAsyncCallback' +import {useSyntheticChange} from '../hooks/useSyntheticChange' +import {FileType} from '../hooks/useUnifiedFileSelect' +import {Actions} from './Actions' +import {Label} from './Label' +import {CoreToolbar, DefaultToolbarButtons, Toolbar} from './Toolbar' +import {Footer} from './_Footer' import {FormattingTools} from './_FormattingTools' import {MarkdownEditorContext} from './_MarkdownEditorContext' -import {CoreToolbar, DefaultToolbarButtons} from './Toolbar' -import {Footer} from './_Footer' import {MarkdownInput} from './_MarkdownInput' +import {SavedRepliesContext, SavedRepliesHandle, SavedReply} from './_SavedReplies' +import {MarkdownViewMode, ViewSwitch} from './_ViewSwitch' import {FileUploadResult, useFileHandling} from './_useFileHandling' import {useIndenting} from './_useIndenting' import {useListEditing} from './_useListEditing' -import {MarkdownViewMode, ViewSwitch} from './_ViewSwitch' -import {useSafeAsyncCallback} from '../hooks/useSafeAsyncCallback' -import {SavedRepliesContext, SavedRepliesHandle, SavedReply} from './_SavedReplies' +import {SuggestionOptions} from './suggestions' import {Emoji} from './suggestions/_useEmojiSuggestions' import {Mentionable} from './suggestions/_useMentionSuggestions' import {Reference} from './suggestions/_useReferenceSuggestions' import {isModifierKey} from './utils' -import {SuggestionOptions} from './suggestions' export type MarkdownEditorProps = SxProp & { /** Current value of the editor as a multiline markdown string. */ @@ -143,9 +145,6 @@ const a11yOnlyStyle = {clipPath: 'Circle(0)', position: 'absolute'} as const const CONDENSED_WIDTH_THRESHOLD = 675 -const {Slot, Slots} = createSlots(['Toolbar', 'Actions', 'Label']) -export const MarkdownEditorSlot = Slot - /** * We want to switch editors from preview mode on cmd/ctrl+shift+P. But in preview mode, * there's no input to focus so we have to bind the event to the document. If there are @@ -189,6 +188,11 @@ const MarkdownEditor = forwardRef( }, ref, ) => { + const [slots, childrenWithoutSlots] = useSlots(children, { + toolbar: Toolbar, + actions: Actions, + label: Label, + }) const [uncontrolledViewMode, uncontrolledSetViewMode] = useState('edit') const [view, setView] = controlledViewMode === undefined @@ -352,123 +356,117 @@ const MarkdownEditor = forwardRef( // We are using MarkdownEditorContext instead of the built-in Slots context because Slots' context is not typesafe return ( - - {slots => ( - -
- -
{children}
- - {slots.Label} - + +
+ +
{childrenWithoutSlots}
+ + {slots.label} + + + + Markdown input: + {view === 'preview' ? ' preview mode selected.' : ' edit mode selected.'} + + + + + + + + {view === 'edit' && + (slots.toolbar ?? ( + + + + ))} + + + + + + + {view === 'preview' && ( - - Markdown input: - {view === 'preview' ? ' preview mode selected.' : ' edit mode selected.'} - - - - - - - - {view === 'edit' && - (slots.Toolbar ?? ( - - - - ))} - - - - - - - {view === 'preview' && ( - -

Rendered Markdown Preview

- -
- )} - -
Rendered Markdown Preview + -
-
- )} - + )} + +
+ +
+
) }, ) diff --git a/src/drafts/MarkdownEditor/Toolbar.tsx b/src/drafts/MarkdownEditor/Toolbar.tsx index ccf37a44ba0..0b975733298 100644 --- a/src/drafts/MarkdownEditor/Toolbar.tsx +++ b/src/drafts/MarkdownEditor/Toolbar.tsx @@ -18,7 +18,6 @@ import {isMacOS} from '@primer/behaviors/utils' import Box from '../../Box' import {IconButton, IconButtonProps} from '../../Button' import {useFocusZone} from '../../hooks/useFocusZone' -import {MarkdownEditorSlot} from './MarkdownEditor' import {MarkdownEditorContext} from './_MarkdownEditorContext' import {SavedRepliesButton} from './_SavedReplies' @@ -143,9 +142,5 @@ export const CoreToolbar = ({children}: {children?: React.ReactNode}) => { ) } -export const Toolbar = ({children}: {children?: React.ReactNode}) => ( - - {children} - -) +export const Toolbar = ({children}: {children?: React.ReactNode}) => {children} Toolbar.displayName = 'MarkdownEditor.Toolbar'