toolbar-items.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import { FC, memo } from 'react'
  2. import { EditorState } from '@codemirror/state'
  3. import { useEditorContext } from '../../../../shared/context/editor-context'
  4. import { ToolbarButton } from './toolbar-button'
  5. import { redo, undo } from '@codemirror/commands'
  6. import * as commands from '../../extensions/toolbar/commands'
  7. import { SectionHeadingDropdown } from './section-heading-dropdown'
  8. import getMeta from '../../../../utils/meta'
  9. import { InsertFigureDropdown } from './insert-figure-dropdown'
  10. import { useTranslation } from 'react-i18next'
  11. import { MathDropdown } from './math-dropdown'
  12. import { TableInserterDropdown } from './table-inserter-dropdown'
  13. import { withinFormattingCommand } from '@/features/source-editor/utils/tree-operations/formatting'
  14. import { bsVersion } from '@/features/utils/bootstrap-5'
  15. const isMac = /Mac/.test(window.navigator?.platform)
  16. export const ToolbarItems: FC<{
  17. state: EditorState
  18. overflowed?: Set<string>
  19. languageName?: string
  20. visual: boolean
  21. listDepth: number
  22. }> = memo(function ToolbarItems({
  23. state,
  24. overflowed,
  25. languageName,
  26. visual,
  27. listDepth,
  28. }) {
  29. const { t } = useTranslation()
  30. const { toggleSymbolPalette, showSymbolPalette } = useEditorContext()
  31. const isActive = withinFormattingCommand(state)
  32. const symbolPaletteAvailable = getMeta('ol-symbolPaletteAvailable')
  33. const showGroup = (group: string) => !overflowed || overflowed.has(group)
  34. return (
  35. <>
  36. {showGroup('group-history') && (
  37. <div
  38. className="ol-cm-toolbar-button-group"
  39. aria-label={t('toolbar_undo_redo_actions')}
  40. >
  41. <ToolbarButton
  42. id="toolbar-undo"
  43. label={t('toolbar_undo')}
  44. command={undo}
  45. icon={bsVersion({ bs5: 'undo', bs3: 'undo' }) as string}
  46. shortcut={isMac ? '⌘Z' : 'Ctrl+Z'}
  47. />
  48. <ToolbarButton
  49. id="toolbar-redo"
  50. label={t('toolbar_redo')}
  51. command={redo}
  52. icon={bsVersion({ bs5: 'redo', bs3: 'repeat' }) as string}
  53. shortcut={isMac ? '⇧⌘Z' : 'Ctrl+Y'}
  54. />
  55. </div>
  56. )}
  57. {languageName === 'latex' && (
  58. <>
  59. {showGroup('group-section') && (
  60. <div
  61. className="ol-cm-toolbar-button-group"
  62. data-overflow="group-section"
  63. aria-label={t('toolbar_text_formatting')}
  64. >
  65. <SectionHeadingDropdown />
  66. </div>
  67. )}
  68. {showGroup('group-format') && (
  69. <div
  70. className="ol-cm-toolbar-button-group"
  71. aria-label={t('toolbar_text_style')}
  72. >
  73. <ToolbarButton
  74. id="toolbar-format-bold"
  75. label={t('toolbar_format_bold')}
  76. command={commands.toggleBold}
  77. active={isActive('\\textbf')}
  78. icon={bsVersion({ bs5: 'format_bold', bs3: 'bold' }) as string}
  79. shortcut={isMac ? '⌘B' : 'Ctrl+B'}
  80. />
  81. <ToolbarButton
  82. id="toolbar-format-italic"
  83. label={t('toolbar_format_italic')}
  84. command={commands.toggleItalic}
  85. active={isActive('\\textit')}
  86. icon={
  87. bsVersion({ bs5: 'format_italic', bs3: 'italic' }) as string
  88. }
  89. shortcut={isMac ? '⌘I' : 'Ctrl+I'}
  90. />
  91. </div>
  92. )}
  93. {showGroup('group-math') && (
  94. <div
  95. className="ol-cm-toolbar-button-group"
  96. data-overflow="group-math"
  97. aria-label={t('toolbar_insert_math_and_symbols')}
  98. >
  99. <MathDropdown />
  100. {symbolPaletteAvailable && (
  101. <ToolbarButton
  102. id="toolbar-toggle-symbol-palette"
  103. label={t('toolbar_toggle_symbol_palette')}
  104. active={showSymbolPalette}
  105. command={toggleSymbolPalette}
  106. icon="Ω"
  107. textIcon
  108. className="ol-cm-toolbar-button-math"
  109. />
  110. )}
  111. </div>
  112. )}
  113. {showGroup('group-misc') && (
  114. <div
  115. className="ol-cm-toolbar-button-group"
  116. data-overflow="group-misc"
  117. aria-label={t('toolbar_insert_misc')}
  118. >
  119. <ToolbarButton
  120. id="toolbar-href"
  121. label={t('toolbar_insert_link')}
  122. command={commands.wrapInHref}
  123. icon={bsVersion({ bs5: 'link', bs3: 'link' }) as string}
  124. />
  125. <ToolbarButton
  126. id="toolbar-ref"
  127. label={t('toolbar_insert_cross_reference')}
  128. command={commands.insertRef}
  129. icon={bsVersion({ bs5: 'sell', bs3: 'tag' }) as string}
  130. />
  131. <ToolbarButton
  132. id="toolbar-cite"
  133. label={t('toolbar_insert_citation')}
  134. command={commands.insertCite}
  135. icon={bsVersion({ bs5: 'menu_book', bs3: 'book' }) as string}
  136. />
  137. <InsertFigureDropdown />
  138. <TableInserterDropdown />
  139. </div>
  140. )}
  141. {showGroup('group-list') && (
  142. <div
  143. className="ol-cm-toolbar-button-group"
  144. data-overflow="group-list"
  145. aria-label={t('toolbar_list_indentation')}
  146. >
  147. <ToolbarButton
  148. id="toolbar-bullet-list"
  149. label={t('toolbar_bullet_list')}
  150. command={commands.toggleBulletList}
  151. icon={
  152. bsVersion({
  153. bs5: 'format_list_bulleted',
  154. bs3: 'list-ul',
  155. }) as string
  156. }
  157. />
  158. <ToolbarButton
  159. id="toolbar-numbered-list"
  160. label={t('toolbar_numbered_list')}
  161. command={commands.toggleNumberedList}
  162. icon={
  163. bsVersion({
  164. bs5: 'format_list_numbered',
  165. bs3: 'list-ol',
  166. }) as string
  167. }
  168. />
  169. <ToolbarButton
  170. id="toolbar-format-indent-decrease"
  171. label={t('toolbar_decrease_indent')}
  172. command={commands.indentDecrease}
  173. icon={
  174. bsVersion({
  175. bs5: 'format_indent_decrease',
  176. bs3: 'outdent',
  177. }) as string
  178. }
  179. shortcut={visual ? (isMac ? '⌘[' : 'Ctrl+[') : undefined}
  180. disabled={listDepth < 2}
  181. />
  182. <ToolbarButton
  183. id="toolbar-format-indent-increase"
  184. label={t('toolbar_increase_indent')}
  185. command={commands.indentIncrease}
  186. icon={
  187. bsVersion({
  188. bs5: 'format_indent_increase',
  189. bs3: 'indent',
  190. }) as string
  191. }
  192. shortcut={visual ? (isMac ? '⌘]' : 'Ctrl+]') : undefined}
  193. disabled={listDepth < 1}
  194. />
  195. </div>
  196. )}
  197. </>
  198. )}
  199. </>
  200. )
  201. })