toolbar-items.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 { InsertListDropdown } from './insert-list-dropdown'
  13. import { TableDropdown } from './table-dropdown'
  14. import { LegacyTableDropdown } from './table-inserter-dropdown-legacy'
  15. import { withinFormattingCommand } from '@/features/source-editor/utils/tree-operations/formatting'
  16. import { isMac } from '@/shared/utils/os'
  17. import { useProjectContext } from '@/shared/context/project-context'
  18. import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
  19. import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
  20. import { isCursorOnEmptyLine } from '@/features/source-editor/utils/is-cursor-on-empty-line'
  21. const addCommentFromToolbar = () => commands.addComment('toolbar')
  22. export const ToolbarItems: FC<{
  23. state: EditorState
  24. overflowed?: Set<string>
  25. languageName?: string
  26. visual: boolean
  27. listDepth: number
  28. }> = memo(function ToolbarItems({
  29. state,
  30. overflowed,
  31. languageName,
  32. visual,
  33. listDepth,
  34. }) {
  35. const { t } = useTranslation()
  36. const { showSymbolPalette, toggleSymbolPalette } =
  37. useEditorPropertiesContext()
  38. const { writefullInstance } = useEditorContext()
  39. const { features } = useProjectContext()
  40. const permissions = usePermissionsContext()
  41. const isActive = withinFormattingCommand(state)
  42. const symbolPaletteAvailable = getMeta('ol-symbolPaletteAvailable')
  43. const showGroup = (group: string) => !overflowed || overflowed.has(group)
  44. return (
  45. <>
  46. {showGroup('group-history') && (
  47. <div
  48. className="ol-cm-toolbar-button-group"
  49. aria-label={t('toolbar_undo_redo_actions')}
  50. >
  51. <ToolbarButton
  52. id="toolbar-undo"
  53. label={t('toolbar_undo')}
  54. command={undo}
  55. icon="undo"
  56. shortcut={isMac ? '⌘Z' : 'Ctrl+Z'}
  57. />
  58. <ToolbarButton
  59. id="toolbar-redo"
  60. label={t('toolbar_redo')}
  61. command={redo}
  62. icon="redo"
  63. shortcut={isMac ? '⇧⌘Z' : 'Ctrl+Y'}
  64. />
  65. </div>
  66. )}
  67. {languageName === 'latex' && (
  68. <>
  69. {showGroup('group-section') && (
  70. <div
  71. className="ol-cm-toolbar-button-group"
  72. data-overflow="group-section"
  73. aria-label={t('toolbar_text_formatting')}
  74. >
  75. <SectionHeadingDropdown />
  76. </div>
  77. )}
  78. {showGroup('group-format') && (
  79. <div
  80. className="ol-cm-toolbar-button-group"
  81. aria-label={t('toolbar_text_style')}
  82. >
  83. <ToolbarButton
  84. id="toolbar-format-bold"
  85. label={t('toolbar_bold')}
  86. command={commands.toggleBold}
  87. active={isActive('\\textbf')}
  88. icon="format_bold"
  89. shortcut={isMac ? '⌘B' : 'Ctrl+B'}
  90. />
  91. <ToolbarButton
  92. id="toolbar-format-italic"
  93. label={t('toolbar_italic')}
  94. command={commands.toggleItalic}
  95. active={isActive('\\textit')}
  96. icon="format_italic"
  97. shortcut={isMac ? '⌘I' : 'Ctrl+I'}
  98. />
  99. </div>
  100. )}
  101. {showGroup('group-math') && (
  102. <div
  103. className="ol-cm-toolbar-button-group"
  104. data-overflow="group-math"
  105. aria-label={t('toolbar_insert_math_and_symbols')}
  106. >
  107. <MathDropdown />
  108. {symbolPaletteAvailable && (
  109. <ToolbarButton
  110. id="toolbar-toggle-symbol-palette"
  111. label={t('toolbar_insert_symbol')}
  112. active={showSymbolPalette}
  113. command={toggleSymbolPalette}
  114. icon="Ω"
  115. textIcon
  116. className="ol-cm-toolbar-button-math"
  117. />
  118. )}
  119. </div>
  120. )}
  121. {showGroup('group-misc') && (
  122. <div
  123. className="ol-cm-toolbar-button-group"
  124. data-overflow="group-misc"
  125. aria-label={t('toolbar_insert_misc')}
  126. >
  127. <ToolbarButton
  128. id="toolbar-href"
  129. label={t('toolbar_insert_link')}
  130. command={commands.wrapInHref}
  131. icon="add_link"
  132. />
  133. {features.trackChangesVisible && permissions.comment && (
  134. <ToolbarButton
  135. id="toolbar-add-comment"
  136. label={t('add_comment')}
  137. disabled={isCursorOnEmptyLine(state)}
  138. command={addCommentFromToolbar}
  139. icon="add_comment"
  140. />
  141. )}
  142. <ToolbarButton
  143. id="toolbar-ref"
  144. label={t('toolbar_insert_cross_reference')}
  145. command={commands.insertRef}
  146. icon="sell"
  147. />
  148. <ToolbarButton
  149. id="toolbar-cite"
  150. label={t('toolbar_insert_citation')}
  151. command={commands.insertCite}
  152. icon="book_5"
  153. />
  154. <InsertFigureDropdown />
  155. {writefullInstance ? <TableDropdown /> : <LegacyTableDropdown />}
  156. </div>
  157. )}
  158. {showGroup('group-list') && (
  159. <div
  160. className="ol-cm-toolbar-button-group"
  161. data-overflow="group-list"
  162. aria-label={t('toolbar_list_indentation')}
  163. >
  164. <InsertListDropdown />
  165. {listDepth >= 1 && (
  166. <>
  167. <ToolbarButton
  168. id="toolbar-format-indent-decrease"
  169. label={t('toolbar_decrease_indent')}
  170. command={commands.indentDecrease}
  171. icon="format_indent_decrease"
  172. shortcut={visual ? (isMac ? '⌘[' : 'Ctrl+[') : undefined}
  173. disabled={listDepth < 2}
  174. />
  175. <ToolbarButton
  176. id="toolbar-format-indent-increase"
  177. label={t('toolbar_increase_indent')}
  178. command={commands.indentIncrease}
  179. icon="format_indent_increase"
  180. shortcut={visual ? (isMac ? '⌘]' : 'Ctrl+]') : undefined}
  181. />
  182. </>
  183. )}
  184. </div>
  185. )}
  186. </>
  187. )}
  188. </>
  189. )
  190. })