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/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 => (
-
-
+ )}
+
+
+
+
+
)
},
)
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'