SnippetRow.tsx73 lines · main
1import { X } from 'lucide-react'
2import React from 'react'
3import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from 'ui'
4import { CodeBlock } from 'ui-patterns/CodeBlock'
5
6import { type SqlSnippet } from './AIAssistant.types'
7
8export const getSnippetLabel = (snippet: SqlSnippet, index: number): string => {
9 if (typeof snippet === 'string') {
10 return `Snippet ${index + 1}`
11 }
12 return snippet.label
13}
14
15export const getSnippetContent = (snippet: SqlSnippet): string => {
16 if (typeof snippet === 'string') {
17 return snippet
18 }
19 return snippet.content
20}
21
22interface SnippetRowProps {
23 snippets: SqlSnippet[]
24 onRemoveSnippet?: (index: number) => void
25 className?: string
26}
27
28export 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}