CollapsibleCodeBlock.tsx50 lines · main
| 1 | import { Code, X } from 'lucide-react' |
| 2 | import { Button, cn, HoverCard, HoverCardContent, HoverCardTrigger } from 'ui' |
| 3 | import { CodeBlock, type CodeBlockProps } from 'ui-patterns/CodeBlock' |
| 4 | |
| 5 | interface CollapsibleCodeBlockProps extends CodeBlockProps { |
| 6 | onRemove?: () => void |
| 7 | } |
| 8 | |
| 9 | export const CollapsibleCodeBlock = ({ onRemove, ...props }: CollapsibleCodeBlockProps) => { |
| 10 | const codeString = (props.value || props.children) as string |
| 11 | const firstLine = codeString?.substring(0, codeString.indexOf('\n')) || codeString |
| 12 | |
| 13 | return ( |
| 14 | <div className="relative"> |
| 15 | <div |
| 16 | className={cn( |
| 17 | 'flex items-center gap-1 px-2 py-1.5 bg-surface-100 border border-default w-full overflow-hidden', |
| 18 | 'rounded-md', |
| 19 | props.className |
| 20 | )} |
| 21 | > |
| 22 | <HoverCard> |
| 23 | <HoverCardTrigger asChild> |
| 24 | <div className="flex flex-1 items-center gap-2 text-foreground-light px-2 hover:text-foreground cursor-pointer overflow-hidden"> |
| 25 | <Code size={14} strokeWidth={1.5} /> |
| 26 | <span className="text-xs font-mono flex-1 truncate pointer">{firstLine}...</span> |
| 27 | </div> |
| 28 | </HoverCardTrigger> |
| 29 | <HoverCardContent className="w-96 max-h-96 overflow-auto p-0"> |
| 30 | <CodeBlock |
| 31 | {...props} |
| 32 | value={codeString} |
| 33 | className={cn('text-xs font-mono border-none p-3')} |
| 34 | /> |
| 35 | </HoverCardContent> |
| 36 | </HoverCard> |
| 37 | |
| 38 | {onRemove && ( |
| 39 | <Button |
| 40 | type="text" |
| 41 | size="tiny" |
| 42 | className="shrink-0 w-6 h-6" |
| 43 | onClick={onRemove} |
| 44 | icon={<X size={14} />} |
| 45 | /> |
| 46 | )} |
| 47 | </div> |
| 48 | </div> |
| 49 | ) |
| 50 | } |