external-tool-option.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { memo } from 'react'
  2. import { MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin'
  3. export class VariableOption extends MenuOption {
  4. title: string
  5. icon?: JSX.Element
  6. extraElement?: JSX.Element
  7. keywords: Array<string>
  8. keyboardShortcut?: string
  9. onSelect: (queryString: string) => void
  10. constructor(
  11. title: string,
  12. options: {
  13. icon?: JSX.Element
  14. extraElement?: JSX.Element
  15. keywords?: Array<string>
  16. keyboardShortcut?: string
  17. onSelect: (queryString: string) => void
  18. },
  19. ) {
  20. super(title)
  21. this.title = title
  22. this.keywords = options.keywords || []
  23. this.icon = options.icon
  24. this.extraElement = options.extraElement
  25. this.keyboardShortcut = options.keyboardShortcut
  26. this.onSelect = options.onSelect.bind(this)
  27. }
  28. }
  29. type VariableMenuItemProps = {
  30. isSelected: boolean
  31. onClick: () => void
  32. onMouseEnter: () => void
  33. option: VariableOption
  34. queryString: string | null
  35. }
  36. export const VariableMenuItem = memo(({
  37. isSelected,
  38. onClick,
  39. onMouseEnter,
  40. option,
  41. queryString,
  42. }: VariableMenuItemProps) => {
  43. const title = option.title
  44. let before = title
  45. let middle = ''
  46. let after = ''
  47. if (queryString) {
  48. const regex = new RegExp(queryString, 'i')
  49. const match = regex.exec(option.title)
  50. if (match) {
  51. before = title.substring(0, match.index)
  52. middle = match[0]
  53. after = title.substring(match.index + match[0].length)
  54. }
  55. }
  56. return (
  57. <div
  58. key={option.key}
  59. className={`
  60. flex items-center px-3 h-6 rounded-md hover:bg-primary-50 cursor-pointer
  61. ${isSelected && 'bg-primary-50'}
  62. `}
  63. tabIndex={-1}
  64. ref={option.setRefElement}
  65. onMouseEnter={onMouseEnter}
  66. onClick={onClick}>
  67. <div className='mr-2'>
  68. {option.icon}
  69. </div>
  70. <div className='grow text-[13px] text-gray-900 truncate' title={option.title}>
  71. {before}
  72. <span className='text-[#2970FF]'>{middle}</span>
  73. {after}
  74. </div>
  75. {option.extraElement}
  76. </div>
  77. )
  78. })
  79. VariableMenuItem.displayName = 'VariableMenuItem'