table-dropdown.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { DropdownHeader } from '@/shared/components/dropdown/dropdown-menu'
  2. import { ToolbarButtonMenu } from './button-menu'
  3. import MaterialIcon from '../../../../shared/components/material-icon'
  4. import { useTranslation } from 'react-i18next'
  5. import { useEditorContext } from '@/shared/context/editor-context'
  6. import { memo, useRef, useCallback } from 'react'
  7. import OLListGroupItem from '@/shared/components/ol/ol-list-group-item'
  8. import sparkleWhite from '@/shared/svgs/sparkle-small-white.svg'
  9. import sparkle from '@/shared/svgs/ai-sparkle-text.svg'
  10. import { TableInserterDropdown } from './table-inserter-dropdown'
  11. import OLOverlay from '@/shared/components/ol/ol-overlay'
  12. import OLPopover from '@/shared/components/ol/ol-popover'
  13. import useDropdown from '../../../../shared/hooks/use-dropdown'
  14. import * as commands from '../../extensions/toolbar/commands'
  15. import { useCodeMirrorViewContext } from '../codemirror-context'
  16. import { emitToolbarEvent } from '../../extensions/toolbar/utils/analytics'
  17. export const TableDropdown = memo(function TableDropdown() {
  18. const { t } = useTranslation()
  19. const { writefullInstance } = useEditorContext()
  20. const selectSizeDropdown = useDropdown()
  21. const target = useRef<any>(null)
  22. const view = useCodeMirrorViewContext()
  23. const onSizeSelected = useCallback(
  24. (sizeX: number, sizeY: number) => {
  25. selectSizeDropdown.onToggle(false)
  26. commands.insertTable(view, sizeX, sizeY)
  27. emitToolbarEvent(view, 'table-generator-insert-table')
  28. view.focus()
  29. },
  30. [selectSizeDropdown, view]
  31. )
  32. return (
  33. <>
  34. <div ref={target}>
  35. <ToolbarButtonMenu
  36. id="toolbar-table"
  37. label={t('toolbar_insert_table')}
  38. disablePopover={selectSizeDropdown.open}
  39. icon={<MaterialIcon type="table_chart" />}
  40. >
  41. <DropdownHeader className="ol-cm-toolbar-header mx-2">
  42. {t('toolbar_table_insert_table_lowercase')}
  43. </DropdownHeader>
  44. <OLListGroupItem
  45. aria-label={t('toolbar_generate_table')}
  46. onClick={() => {
  47. writefullInstance?.openTableGenerator()
  48. }}
  49. >
  50. <img
  51. alt="sparkle"
  52. className="ol-cm-toolbar-ai-sparkle-gradient"
  53. src={sparkle}
  54. aria-hidden="true"
  55. />
  56. <img
  57. alt="sparkle"
  58. className="ol-cm-toolbar-ai-sparkle-white"
  59. src={sparkleWhite}
  60. aria-hidden="true"
  61. />
  62. <span>{t('generate_from_text_or_image')}</span>
  63. </OLListGroupItem>
  64. <div className="ol-cm-toolbar-dropdown-divider mx-2 my-0" />
  65. <OLListGroupItem
  66. aria-label={t('toolbar_insert_table')}
  67. onMouseDown={event => {
  68. event.preventDefault()
  69. event.stopPropagation()
  70. }}
  71. onClick={event => {
  72. selectSizeDropdown.onToggle(!selectSizeDropdown.open)
  73. // prevent click event from bubbling up to the toolbar overflow button causing it to close
  74. event.stopPropagation()
  75. }}
  76. >
  77. <span>{t('select_size')}</span>
  78. </OLListGroupItem>
  79. </ToolbarButtonMenu>
  80. <OLOverlay
  81. show={selectSizeDropdown.open}
  82. target={target.current}
  83. placement="bottom"
  84. container={view.dom}
  85. containerPadding={0}
  86. transition
  87. rootClose
  88. onHide={() => selectSizeDropdown.onToggle(false)}
  89. >
  90. <OLPopover
  91. id="toolbar-table-menu"
  92. ref={selectSizeDropdown.ref}
  93. className="ol-cm-toolbar-button-menu-popover ol-cm-toolbar-button-menu-popover-unstyled"
  94. >
  95. <TableInserterDropdown onSizeSelected={onSizeSelected} />
  96. </OLPopover>
  97. </OLOverlay>
  98. </div>
  99. </>
  100. )
  101. })