RemarkVarPicker.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import { Tag, Tooltip, Typography } from 'antd';
  2. import { useTranslation } from 'react-i18next';
  3. import { REMARK_VARIABLES, REMARK_VAR_GROUPS, wrapToken } from '@/lib/remark/remarkVariables';
  4. import type { RemarkVar } from '@/lib/remark/remarkVariables';
  5. import { activateOnKey } from '@/utils/a11y';
  6. interface RemarkVarPickerProps {
  7. /** Called with the bare token (e.g. "EMAIL") when a chip is clicked. */
  8. onPick: (token: string) => void;
  9. variables?: RemarkVar[];
  10. }
  11. /**
  12. * RemarkVarPicker is the grouped, tooltipped chip list of {{VAR}} tokens used by
  13. * the global remark-template field.
  14. */
  15. export default function RemarkVarPicker({ onPick, variables = REMARK_VARIABLES }: RemarkVarPickerProps) {
  16. const { t } = useTranslation();
  17. return (
  18. <div style={{ maxWidth: 460, maxHeight: 'min(70vh, 640px)', overflowY: 'auto' }}>
  19. <Typography.Paragraph type="secondary" style={{ fontSize: 12, marginBottom: 8 }}>
  20. {t('pages.hosts.remarkVars.intro')}
  21. </Typography.Paragraph>
  22. {REMARK_VAR_GROUPS.filter((group) => variables.some((v) => v.group === group)).map((group) => (
  23. <div key={group} style={{ marginBottom: 8 }}>
  24. <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', opacity: 0.6, marginBottom: 4 }}>
  25. {t(`pages.hosts.remarkVars.groups.${group}`)}
  26. </div>
  27. <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
  28. {variables.filter((v) => v.group === group).map((v) => (
  29. <Tooltip key={v.token} title={t(`pages.hosts.remarkVars.desc${v.token}`)}>
  30. <Tag
  31. role="button"
  32. tabIndex={0}
  33. onClick={() => onPick(v.token)}
  34. onKeyDown={activateOnKey(() => onPick(v.token))}
  35. style={{ cursor: 'pointer', margin: 0, fontFamily: 'monospace' }}
  36. >
  37. {wrapToken(v.token)}
  38. </Tag>
  39. </Tooltip>
  40. ))}
  41. </div>
  42. </div>
  43. ))}
  44. </div>
  45. );
  46. }