Skip to content

Commit b129e2e

Browse files
committed
fix: tabs/framework hydration mismatch
1 parent 2a43713 commit b129e2e

File tree

6 files changed

+6
-25
lines changed

6 files changed

+6
-25
lines changed

src/components/markdown/FileTabs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ export type FileTabDefinition = {
88
export type FileTabsProps = {
99
tabs: Array<FileTabDefinition>
1010
children: Array<React.ReactNode> | React.ReactNode
11-
id: string
1211
}
1312

14-
export function FileTabs({ tabs, id, children }: FileTabsProps) {
13+
export function FileTabs({ tabs, children }: FileTabsProps) {
14+
const id = React.useId()
1515
const childrenArray = React.Children.toArray(children)
1616
const [activeSlug, setActiveSlug] = React.useState(tabs[0]?.slug ?? '')
1717

src/components/markdown/FrameworkContent.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ type CodeBlockMeta = {
1212
}
1313

1414
type FrameworkContentProps = {
15-
id: string
1615
codeBlocksByFramework: Record<string, CodeBlockMeta[]>
1716
availableFrameworks: string[]
1817
/** Pre-rendered React children for each framework (from domToReact) */
@@ -27,7 +26,6 @@ type FrameworkContentProps = {
2726
* - If no code blocks but has content: shows the content directly
2827
*/
2928
export function FrameworkContent({
30-
id,
3129
codeBlocksByFramework,
3230
panelsByFramework,
3331
}: FrameworkContentProps) {
@@ -72,9 +70,7 @@ export function FrameworkContent({
7270

7371
return (
7472
<div className="framework-content">
75-
<Tabs id={`${id}-${normalizedFramework}`} tabs={tabs} variant="files">
76-
{childrenArray}
77-
</Tabs>
73+
<Tabs tabs={tabs}>{childrenArray}</Tabs>
7874
</div>
7975
)
8076
}

src/components/markdown/MarkdownFrameworkHandler.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ export function handleFrameworkComponent(
3636
const availableFrameworks = JSON.parse(
3737
domNode.attribs['data-available-frameworks'] || '[]',
3838
)
39-
const id =
40-
attributes.id || `framework-${Math.random().toString(36).slice(2, 9)}`
4139

4240
const panelElements = domNode.children?.filter(
4341
(child): child is Element =>
@@ -56,7 +54,6 @@ export function handleFrameworkComponent(
5654
return (
5755
<React.Suspense fallback={<div>Loading...</div>}>
5856
<FrameworkContent
59-
id={id}
6057
codeBlocksByFramework={codeBlocksByFramework}
6158
availableFrameworks={availableFrameworks}
6259
panelsByFramework={panelsByFramework}

src/components/markdown/MarkdownTabsHandler.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,11 @@ export function handleTabsComponent(
4343
if (pmMeta) {
4444
try {
4545
const { packagesByFramework, mode } = JSON.parse(pmMeta)
46-
const id =
47-
attributes.id ||
48-
`package-manager-tabs-${Math.random().toString(36).slice(2, 9)}`
4946
const frameworks = Object.keys(packagesByFramework) as Framework[]
5047

5148
return (
5249
<React.Suspense fallback={<div>Loading...</div>}>
5350
<PackageManagerTabs
54-
id={id}
5551
packagesByFramework={packagesByFramework}
5652
mode={mode}
5753
frameworks={frameworks}
@@ -68,8 +64,6 @@ export function handleTabsComponent(
6864
if (filesMeta) {
6965
try {
7066
const tabs = attributes.tabs || []
71-
const id =
72-
attributes.id || `files-tabs-${Math.random().toString(36).slice(2, 9)}`
7367

7468
const panelElements = domNode.children?.filter(
7569
(child): child is Element =>
@@ -82,7 +76,7 @@ export function handleTabsComponent(
8276

8377
return (
8478
<React.Suspense fallback={<div>Loading...</div>}>
85-
<FileTabs id={id} tabs={tabs} children={children as any} />
79+
<FileTabs tabs={tabs} children={children as any} />
8680
</React.Suspense>
8781
)
8882
} catch {
@@ -92,7 +86,6 @@ export function handleTabsComponent(
9286

9387
// Handle default tabs variant
9488
const tabs = attributes.tabs
95-
const id = attributes.id || `tabs-${Math.random().toString(36).slice(2, 9)}`
9689

9790
if (!tabs || !Array.isArray(tabs)) {
9891
return null
@@ -111,7 +104,7 @@ export function handleTabsComponent(
111104

112105
return (
113106
<React.Suspense fallback={<div>Loading...</div>}>
114-
<Tabs id={id} tabs={tabs} children={children as any} />
107+
<Tabs tabs={tabs} children={children as any} />
115108
</React.Suspense>
116109
)
117110
}

src/components/markdown/PackageManagerTabs.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const usePackageManagerStore = create<{
3131
}))
3232

3333
type PackageManagerTabsProps = {
34-
id: string
3534
packagesByFramework: Record<string, string[][]>
3635
mode: InstallMode
3736
frameworks: Framework[]
@@ -151,7 +150,6 @@ function getInstallCommand(
151150
}
152151

153152
export function PackageManagerTabs({
154-
id,
155153
packagesByFramework,
156154
mode,
157155
}: PackageManagerTabsProps) {
@@ -202,7 +200,6 @@ export function PackageManagerTabs({
202200
return (
203201
<div className="package-manager-tabs">
204202
<Tabs
205-
id={id}
206203
tabs={tabs}
207204
children={children}
208205
activeSlug={selectedPackageManager}

src/components/markdown/Tabs.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@ export type TabDefinition = {
1111
export type TabsProps = {
1212
tabs?: Array<TabDefinition>
1313
children?: Array<React.ReactNode> | React.ReactNode
14-
id: string
1514
activeSlug?: string
1615
onTabChange?: (slug: string) => void
17-
variant?: string
1816
}
1917

2018
export function Tabs({
2119
tabs: tabsProp = [],
22-
id,
2320
children: childrenProp,
2421
activeSlug: controlledActiveSlug,
2522
onTabChange,
2623
}: TabsProps) {
24+
const id = React.useId()
2725
const childrenArray = React.Children.toArray(childrenProp)
2826

2927
const params = useParams({ strict: false })

0 commit comments

Comments
 (0)