|
2 | 2 |
|
3 | 3 | import dynamic from 'next/dynamic'; |
4 | 4 |
|
5 | | -import { getModuleBySlug } from '@/lib/registry'; |
| 5 | +import { getModule } from '@/lib/registry'; |
6 | 6 |
|
7 | 7 | import { PlaygroundProvider } from './PlaygroundContext'; |
8 | 8 | import { ViewSource } from './ViewSource'; |
9 | 9 |
|
10 | | -const docModules: Record<string, React.ComponentType> = { |
11 | | - button: dynamic(() => import('../stories/button.mdx')), |
12 | | - input: dynamic(() => import('../stories/input.mdx')), |
13 | | - // Headless primitives — alphabetical. |
14 | | - accordion: dynamic(() => import('../stories/accordion.mdx')), |
15 | | - autocomplete: dynamic(() => import('../stories/autocomplete.mdx')), |
16 | | - collapsible: dynamic(() => import('../stories/collapsible.mdx')), |
17 | | - dialog: dynamic(() => import('../stories/dialog.mdx')), |
18 | | - menu: dynamic(() => import('../stories/menu.mdx')), |
19 | | - popover: dynamic(() => import('../stories/popover.mdx')), |
20 | | - select: dynamic(() => import('../stories/select.mdx')), |
21 | | - tabs: dynamic(() => import('../stories/tabs.mdx')), |
22 | | - tooltip: dynamic(() => import('../stories/tooltip.mdx')), |
| 10 | +// MDX docs keyed by `group` slug → `component` slug. Group-aware so identically-named |
| 11 | +// entries (the headless `Dialog` primitive vs. the styled `Dialog` component) stay distinct. |
| 12 | +const docModules: Record<string, Record<string, React.ComponentType>> = { |
| 13 | + components: { |
| 14 | + button: dynamic(() => import('../stories/button.mdx')), |
| 15 | + input: dynamic(() => import('../stories/input.mdx')), |
| 16 | + dialog: dynamic(() => import('../stories/dialog.component.mdx')), |
| 17 | + }, |
| 18 | + primitives: { |
| 19 | + // Headless primitives — alphabetical. |
| 20 | + accordion: dynamic(() => import('../stories/accordion.mdx')), |
| 21 | + autocomplete: dynamic(() => import('../stories/autocomplete.mdx')), |
| 22 | + collapsible: dynamic(() => import('../stories/collapsible.mdx')), |
| 23 | + dialog: dynamic(() => import('../stories/dialog.mdx')), |
| 24 | + menu: dynamic(() => import('../stories/menu.mdx')), |
| 25 | + popover: dynamic(() => import('../stories/popover.mdx')), |
| 26 | + select: dynamic(() => import('../stories/select.mdx')), |
| 27 | + tabs: dynamic(() => import('../stories/tabs.mdx')), |
| 28 | + tooltip: dynamic(() => import('../stories/tooltip.mdx')), |
| 29 | + }, |
23 | 30 | }; |
24 | 31 |
|
25 | 32 | interface DocsViewerProps { |
| 33 | + group: string; |
26 | 34 | slug: string; |
27 | 35 | } |
28 | 36 |
|
29 | | -export function DocsViewer({ slug }: DocsViewerProps) { |
30 | | - const DocContent = docModules[slug]; |
| 37 | +export function DocsViewer({ group, slug }: DocsViewerProps) { |
| 38 | + const DocContent = docModules[group]?.[slug]; |
31 | 39 | if (!DocContent) { |
32 | | - return <div className='text-muted-foreground p-8 text-sm'>No docs found for "{slug}".</div>; |
| 40 | + return ( |
| 41 | + <div className='text-muted-foreground p-8 text-sm'> |
| 42 | + No docs found for "{group}/{slug}". |
| 43 | + </div> |
| 44 | + ); |
33 | 45 | } |
34 | | - const meta = getModuleBySlug(slug)?.meta; |
| 46 | + const meta = getModule(group, slug)?.meta; |
35 | 47 | return ( |
36 | | - // Keyed by slug so navigating between components resets the playground state. |
| 48 | + // Keyed by group/slug so navigating between components resets the playground state. |
37 | 49 | <PlaygroundProvider |
38 | | - key={slug} |
| 50 | + key={`${group}/${slug}`} |
39 | 51 | meta={meta} |
40 | 52 | > |
41 | 53 | <article className='prose relative mx-auto w-full min-w-0 max-w-3xl p-8'> |
|
0 commit comments