"use client"; import { memo, useRef, useState, type ReactNode } from "react"; import { IconListCheck, IconFile, IconMessageDots, IconPhoto, IconAt, IconGitPullRequest, IconX, IconPinFilled, } from "@tabler/icons-react"; import type { TablerIcon } from "@tabler/icons-react"; import { HoverCard, HoverCardTrigger, HoverCardContent } from "@kandev/ui/hover-card"; import type { ContextItemKind } from "@/lib/types/context"; const ICON_BY_KIND: Record = { plan: IconListCheck, file: IconFile, comment: IconMessageDots, "plan-comment": IconMessageDots, image: IconPhoto, "file-attachment": IconFile, prompt: IconAt, "pr-feedback": IconGitPullRequest, }; type ContextChipProps = { kind: ContextItemKind; label: string; pinned?: boolean; preview?: ReactNode; /** Data URL to render as a tiny thumbnail instead of the default icon */ thumbnail?: string; onClick?: () => void; onUnpin?: () => void; onRemove?: () => void; }; export const ContextChip = memo(function ContextChip({ kind, label, pinned, preview, thumbnail, onClick, onUnpin, onRemove, }: ContextChipProps) { const Icon = ICON_BY_KIND[kind]; const chip = (
{thumbnail ? ( // eslint-disable-next-line @next/next/no-img-element -- base64 thumbnail ) : ( )} {label} {pinned && onUnpin && ( )} {onRemove && ( )}
); if (!preview) return chip; return {chip}; }); function ControlledHoverChip({ preview, children }: { preview: ReactNode; children: ReactNode }) { const [open, setOpen] = useState(false); const suppressRef = useRef(false); return ( { if (next && suppressRef.current) return; setOpen(next); }} openDelay={300} closeDelay={0} > { suppressRef.current = true; setOpen(false); setTimeout(() => { suppressRef.current = false; }, 300); }} > {children} {preview} ); }