'use client' import { CopyButton } from '@duck-docs/components/copy-button' import { Icons } from '@duck-docs/components/icons' import { useRegistryIndex } from '@duck-docs/context' import { cn } from '@gentleduck/libs/cn' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@gentleduck/registry-ui/tabs' import * as React from 'react' interface IComponentPreviewProps extends React.HTMLAttributes { name: string extractClassname?: boolean extractedClassNames?: string align?: 'center' | 'start' | 'end' description?: string hideCode?: boolean showSettings?: boolean } type CodeFragmentProps = { 'data-dmc-fragment'?: unknown children?: React.ReactNode } type CopyValueProps = { __dmcRaw__?: string value?: string } function getCodeStringFromFragment(codeNode: React.ReactElement | undefined): string | null { if (!codeNode || !React.isValidElement(codeNode)) { return null } if (typeof codeNode.props['data-dmc-fragment'] === 'undefined') { return null } const fragmentChildren = React.Children.toArray(codeNode.props.children) const copyNode = fragmentChildren[1] if (!copyNode || !React.isValidElement(copyNode)) { return null } return copyNode.props.value ?? copyNode.props.__dmcRaw__ ?? null } export function ComponentPreview({ name, children, className, extractClassname, extractedClassNames, align = 'center', description, hideCode = false, showSettings = false, ...props }: IComponentPreviewProps) { const Codes = React.Children.toArray(children) as React.ReactElement[] const Code = Codes[0] const registryIndex = useRegistryIndex() // `` receives pre-resolved children from the // build pipeline — one fenced code block per file, highlighted upstream. const Preview = React.useMemo(() => { if (!registryIndex) { return (
Registry index is not configured for this docs app.
) } const Component = registryIndex[name]?.component if (!Component) { return (
Component{' '} {name} not found in registry.
) } return }, [name, registryIndex]) const codeString = React.useMemo(() => getCodeStringFromFragment(Code), [Code]) return (
{!hideCode && ( {TABS.map((tab) => ( {tab.name} ))} )}
{}
{Code ?? ( )}
) } export const TABS = [ { name: 'Preview', value: 'preview', }, { name: 'Code', value: 'code', }, ]