ReferenceChip.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { X } from "lucide-react"
  2. import type { ReferenceToken } from "@/lib/reference/types"
  3. const categoryColors: Record<ReferenceToken["category"], string> = {
  4. chapter: "bg-purple-100 text-purple-700 border-purple-300",
  5. memory: "bg-green-100 text-green-700 border-green-300",
  6. outline: "bg-blue-100 text-blue-700 border-blue-300",
  7. deduction: "bg-orange-100 text-orange-700 border-orange-300",
  8. skill: "bg-yellow-100 text-yellow-700 border-yellow-300",
  9. chat_history: "bg-cyan-100 text-cyan-700 border-cyan-300",
  10. outline_history: "bg-indigo-100 text-indigo-700 border-indigo-300",
  11. }
  12. interface ReferenceChipProps {
  13. token: ReferenceToken
  14. readonly?: boolean
  15. onRemove?: (id: string) => void
  16. }
  17. export function ReferenceChip({
  18. token,
  19. readonly = false,
  20. onRemove,
  21. }: ReferenceChipProps) {
  22. const colorClass = categoryColors[token.category]
  23. return (
  24. <span
  25. className={`mx-0.5 inline-flex items-center gap-1 rounded-md border px-2 py-0.5 text-xs font-medium ${colorClass}`}
  26. contentEditable={readonly ? undefined : false}
  27. data-reference-id={token.id}
  28. data-reference-category={token.category}
  29. >
  30. @{token.displayTitle}
  31. {!readonly && (
  32. <button
  33. type="button"
  34. className="ml-0.5 cursor-pointer rounded-sm p-0.5 text-muted-foreground hover:bg-destructive/10 hover:text-destructive"
  35. onClick={(event) => {
  36. event.preventDefault()
  37. onRemove?.(token.id)
  38. }}
  39. tabIndex={-1}
  40. aria-label={`移除引用 ${token.displayTitle}`}
  41. >
  42. <X className="h-3 w-3" aria-hidden="true" />
  43. </button>
  44. )}
  45. </span>
  46. )
  47. }