| 137 | } |
| 138 | |
| 139 | function CodePanel({ |
| 140 | children, |
| 141 | tag, |
| 142 | label, |
| 143 | code |
| 144 | }: { |
| 145 | children: React.ReactNode; |
| 146 | tag?: string; |
| 147 | label?: string; |
| 148 | code?: string; |
| 149 | }) { |
| 150 | let child = Children.only(children); |
| 151 | |
| 152 | if (isValidElement(child)) { |
| 153 | const props = child.props as { tag?: string; label?: string; code?: string }; |
| 154 | tag = props.tag ?? tag; |
| 155 | label = props.label ?? label; |
| 156 | code = props.code ?? code; |
| 157 | } |
| 158 | |
| 159 | if (!code) { |
| 160 | throw new Error( |
| 161 | '`CodePanel` requires a `code` prop, or a child with a `code` prop.' |
| 162 | ); |
| 163 | } |
| 164 | |
| 165 | return ( |
| 166 | <div className={cn("group px-[6px] pb-[6px]", !tag && !label && 'pt-[6px]')}> |
| 167 | <CodePanelHeader tag={tag} label={label} /> |
| 168 | <div |
| 169 | className={cn( |
| 170 | 'relative bg-muted', |
| 171 | 'rounded-xl border border-border bg-foreground px-4 py-4 shadow-sm ring-0 dark:border-none dark:bg-muted', |
| 172 | 'dark:shadow-[0_2px_3px_0_theme(colors.black/35%),0_0_0_1px_theme(colors.white/10%),0_-1px_0_0_theme(colors.white/3%)]' |
| 173 | )} |
| 174 | > |
| 175 | <pre className="overflow-x-auto text-xs text-white"> |
| 176 | {children} |
| 177 | </pre> |
| 178 | <CopyButton code={code} /> |
| 179 | </div> |
| 180 | </div> |
| 181 | ); |
| 182 | } |
| 183 | |
| 184 | function CodeGroupHeader({ |
| 185 | title, |