@@ -15,6 +15,8 @@ import { Tabs } from '~/components/Tabs'
1515import { CodeBlock } from './CodeBlock'
1616import { PackageManagerTabs } from './PackageManagerTabs'
1717import type { Framework } from '~/libraries/types'
18+ import { FileTabs } from './FileTabs'
19+ import { FrameworkCodeBlock } from './FrameworkCodeBlock'
1820
1921type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
2022
@@ -124,7 +126,6 @@ const options: HTMLReactParserOptions = {
124126
125127 switch ( componentName ?. toLowerCase ( ) ) {
126128 case 'tabs' : {
127- // Check if this is a package-manager tabs (has metadata)
128129 if ( pmMeta ) {
129130 try {
130131 const { packagesByFramework, mode } = JSON . parse ( pmMeta )
@@ -148,7 +149,73 @@ const options: HTMLReactParserOptions = {
148149 }
149150 }
150151
151- // Default tabs variant
152+ // Check if this is files variant
153+ const filesMeta = domNode . attribs [ 'data-files-meta' ]
154+ if ( filesMeta ) {
155+ try {
156+ const tabs = attributes . tabs || [ ]
157+ const id =
158+ attributes . id ||
159+ `files-tabs-${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } `
160+
161+ const panelElements = domNode . children ?. filter (
162+ ( child ) : child is Element =>
163+ child instanceof Element && child . name === 'md-tab-panel' ,
164+ )
165+
166+ const children = panelElements ?. map ( ( panel ) =>
167+ domToReact ( panel . children as any , options ) ,
168+ )
169+
170+ return (
171+ < FileTabs id = { id } tabs = { tabs } children = { children as any } />
172+ )
173+ } catch {
174+ // Fall through to default tabs if parsing fails
175+ }
176+ }
177+
178+ const frameworkMeta = domNode . attribs [ 'data-framework-meta' ]
179+ if ( frameworkMeta ) {
180+ try {
181+ const { codeBlocksByFramework } = JSON . parse ( frameworkMeta )
182+ const availableFrameworks = JSON . parse (
183+ domNode . attribs [ 'data-available-frameworks' ] || '[]' ,
184+ )
185+ const id =
186+ attributes . id ||
187+ `framework-${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } `
188+
189+ const panelElements = domNode . children ?. filter (
190+ ( child ) : child is Element =>
191+ child instanceof Element && child . name === 'md-tab-panel' ,
192+ )
193+
194+ // Build panelsByFramework map
195+ const panelsByFramework : Record < string , React . ReactNode > = { }
196+ panelElements ?. forEach ( ( panel ) => {
197+ const fw = panel . attribs [ 'data-framework' ]
198+ if ( fw ) {
199+ panelsByFramework [ fw ] = domToReact (
200+ panel . children as any ,
201+ options ,
202+ )
203+ }
204+ } )
205+
206+ return (
207+ < FrameworkCodeBlock
208+ id = { id }
209+ codeBlocksByFramework = { codeBlocksByFramework }
210+ availableFrameworks = { availableFrameworks }
211+ panelsByFramework = { panelsByFramework }
212+ />
213+ )
214+ } catch {
215+ // Fall through to default tabs if parsing fails
216+ }
217+ }
218+
152219 const tabs = attributes . tabs
153220 const id =
154221 attributes . id || `tabs-${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } `
@@ -162,9 +229,11 @@ const options: HTMLReactParserOptions = {
162229 child instanceof Element && child . name === 'md-tab-panel' ,
163230 )
164231
165- const children = panelElements ?. map ( ( panel ) =>
166- domToReact ( panel . children as any , options ) ,
167- )
232+ const children = panelElements ?. map ( ( panel ) => {
233+ const result = domToReact ( panel . children as any , options )
234+ // Wrap in fragment to ensure it's a single React node
235+ return < > { result } </ >
236+ } )
168237
169238 return < Tabs id = { id } tabs = { tabs } children = { children as any } />
170239 }
0 commit comments