SnippetRow.tsx73 lines · main
| 1 | import { X } from 'lucide-react' |
| 2 | import React from 'react' |
| 3 | import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from 'ui' |
| 4 | import { CodeBlock } from 'ui-patterns/CodeBlock' |
| 5 | |
| 6 | import { type SqlSnippet } from './AIAssistant.types' |
| 7 | |
| 8 | export const getSnippetLabel = (snippet: SqlSnippet, index: number): string => { |
| 9 | if (typeof snippet === 'string') { |
| 10 | return `Snippet ${index + 1}` |
| 11 | } |
| 12 | return snippet.label |
| 13 | } |
| 14 | |
| 15 | export const getSnippetContent = (snippet: SqlSnippet): string => { |
| 16 | if (typeof snippet === 'string') { |
| 17 | return snippet |
| 18 | } |
| 19 | return snippet.content |
| 20 | } |
| 21 | |
| 22 | interface SnippetRowProps { |
| 23 | snippets: SqlSnippet[] |
| 24 | onRemoveSnippet?: (index: number) => void |
| 25 | className?: string |
| 26 | } |
| 27 | |
| 28 | export const SnippetRow: React.FC<SnippetRowProps> = ({ |
| 29 | snippets, |
| 30 | onRemoveSnippet, |
| 31 | className = '', |
| 32 | }) => { |
| 33 | if (!snippets || snippets.length === 0) return null |
| 34 | |
| 35 | return ( |
| 36 | <div className={`w-full overflow-x-auto flex ${className}`}> |
| 37 | {snippets.map((snippet, idx) => ( |
| 38 | <HoverCard key={idx}> |
| 39 | <HoverCardTrigger asChild> |
| 40 | <div |
| 41 | tabIndex={0} |
| 42 | className="border bg inline-flex gap-1 items-center shrink-0 py-1 pl-2 rounded-full pr-1 text-xs cursor-pointer" |
| 43 | > |
| 44 | {getSnippetLabel(snippet, idx)} |
| 45 | {onRemoveSnippet && ( |
| 46 | <Button |
| 47 | size="tiny" |
| 48 | type="text" |
| 49 | className="h-4! w-4! rounded-full p-0" |
| 50 | onClick={(e) => { |
| 51 | e.stopPropagation() |
| 52 | onRemoveSnippet(idx) |
| 53 | }} |
| 54 | aria-label={`Remove snippet ${idx + 1}`} |
| 55 | icon={<X strokeWidth={1.5} className="h-3! w-3!" />} |
| 56 | /> |
| 57 | )} |
| 58 | </div> |
| 59 | </HoverCardTrigger> |
| 60 | <HoverCardContent className="w-96 max-h-64 overflow-auto p-0"> |
| 61 | <CodeBlock |
| 62 | hideLineNumbers |
| 63 | className="text-xs font-mono whitespace-pre-wrap wrap-break-word p-2 border-0" |
| 64 | language="sql" |
| 65 | > |
| 66 | {getSnippetContent(snippet)} |
| 67 | </CodeBlock> |
| 68 | </HoverCardContent> |
| 69 | </HoverCard> |
| 70 | ))} |
| 71 | </div> |
| 72 | ) |
| 73 | } |