SlashCommandItem.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import React from "react"
  2. import { Edit, Trash2 } from "lucide-react"
  3. import type { Command } from "@roo/ExtensionMessage"
  4. import { useAppTranslation } from "@/i18n/TranslationContext"
  5. import { Button, StandardTooltip } from "@/components/ui"
  6. import { vscode } from "@/utils/vscode"
  7. interface SlashCommandItemProps {
  8. command: Command
  9. onDelete: (command: Command) => void
  10. onClick?: (command: Command) => void
  11. }
  12. export const SlashCommandItem: React.FC<SlashCommandItemProps> = ({ command, onDelete, onClick }) => {
  13. const { t } = useAppTranslation()
  14. // Built-in commands cannot be edited or deleted
  15. const isBuiltIn = command.source === "built-in"
  16. const handleEdit = () => {
  17. if (command.filePath) {
  18. vscode.postMessage({
  19. type: "openFile",
  20. text: command.filePath,
  21. })
  22. } else {
  23. // Fallback: request to open command file by name and source
  24. vscode.postMessage({
  25. type: "openCommandFile",
  26. text: command.name,
  27. values: { source: command.source },
  28. })
  29. }
  30. }
  31. const handleDelete = () => {
  32. onDelete(command)
  33. }
  34. return (
  35. <div className="px-4 py-2 text-sm flex items-center group hover:bg-vscode-list-hoverBackground">
  36. {/* Command name - clickable */}
  37. <div className="flex-1 min-w-0 cursor-pointer" onClick={() => onClick?.(command)}>
  38. <div>
  39. <span className="truncate text-vscode-foreground">{command.name}</span>
  40. {command.description && (
  41. <div className="text-xs text-vscode-descriptionForeground truncate mt-0.5">
  42. {command.description}
  43. </div>
  44. )}
  45. </div>
  46. </div>
  47. {/* Action buttons - only show for non-built-in commands */}
  48. {!isBuiltIn && (
  49. <div className="flex items-center gap-2 ml-2">
  50. <StandardTooltip content={t("chat:slashCommands.editCommand")}>
  51. <Button
  52. variant="ghost"
  53. size="icon"
  54. tabIndex={-1}
  55. onClick={handleEdit}
  56. className="size-6 flex items-center justify-center opacity-60 hover:opacity-100">
  57. <Edit className="w-4 h-4" />
  58. </Button>
  59. </StandardTooltip>
  60. <StandardTooltip content={t("chat:slashCommands.deleteCommand")}>
  61. <Button
  62. variant="ghost"
  63. size="icon"
  64. tabIndex={-1}
  65. onClick={handleDelete}
  66. className="size-6 flex items-center justify-center opacity-60 hover:opacity-100 hover:text-red-400">
  67. <Trash2 className="w-4 h-4" />
  68. </Button>
  69. </StandardTooltip>
  70. </div>
  71. )}
  72. </div>
  73. )
  74. }