editor-switch.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { ChangeEvent, FC, memo, useCallback } from 'react'
  2. import OLTooltip from '@/shared/components/ol/ol-tooltip'
  3. import { sendMB } from '../../../infrastructure/event-tracking'
  4. import { useTranslation } from 'react-i18next'
  5. import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
  6. import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
  7. import { isVisualEditorAvailable } from '../utils/visual-editor'
  8. function EditorSwitch() {
  9. const { t } = useTranslation()
  10. const { showVisual: visual, setShowVisual: setVisual } =
  11. useEditorPropertiesContext()
  12. const { openDocName } = useEditorOpenDocContext()
  13. const richTextAvailable = openDocName
  14. ? isVisualEditorAvailable(openDocName)
  15. : false
  16. const handleChange = useCallback(
  17. (event: ChangeEvent<HTMLInputElement>) => {
  18. const editorType = event.target.value
  19. switch (editorType) {
  20. case 'cm6':
  21. setVisual(false)
  22. break
  23. case 'rich-text':
  24. setVisual(true)
  25. break
  26. }
  27. sendMB('editor-switch-change', { editorType })
  28. },
  29. [setVisual]
  30. )
  31. return (
  32. <div
  33. className="editor-toggle-switch"
  34. aria-label={t('toolbar_code_visual_editor_switch')}
  35. >
  36. <fieldset className="toggle-switch">
  37. <legend className="visually-hidden">Editor mode.</legend>
  38. <input
  39. type="radio"
  40. name="editor"
  41. value="cm6"
  42. id="editor-switch-cm6"
  43. className="toggle-switch-input"
  44. checked={!richTextAvailable || !visual}
  45. onChange={handleChange}
  46. />
  47. <label htmlFor="editor-switch-cm6" className="toggle-switch-label">
  48. <span>{t('code_editor')}</span>
  49. </label>
  50. <RichTextToggle
  51. checked={richTextAvailable && visual}
  52. disabled={!richTextAvailable}
  53. handleChange={handleChange}
  54. />
  55. </fieldset>
  56. </div>
  57. )
  58. }
  59. const RichTextToggle: FC<{
  60. checked: boolean
  61. disabled: boolean
  62. handleChange: (event: ChangeEvent<HTMLInputElement>) => void
  63. }> = ({ checked, disabled, handleChange }) => {
  64. const { t } = useTranslation()
  65. const toggle = (
  66. <span>
  67. <input
  68. type="radio"
  69. name="editor"
  70. value="rich-text"
  71. id="editor-switch-rich-text"
  72. className="toggle-switch-input"
  73. checked={checked}
  74. onChange={handleChange}
  75. disabled={disabled}
  76. />
  77. <label htmlFor="editor-switch-rich-text" className="toggle-switch-label">
  78. <span>{t('visual_editor')}</span>
  79. </label>
  80. </span>
  81. )
  82. if (disabled) {
  83. return (
  84. <OLTooltip
  85. description={t('visual_editor_is_only_available_for_tex_files')}
  86. id="rich-text-toggle-tooltip"
  87. overlayProps={{ placement: 'bottom' }}
  88. tooltipProps={{ className: 'tooltip-wide' }}
  89. >
  90. {toggle}
  91. </OLTooltip>
  92. )
  93. }
  94. return (
  95. <OLTooltip
  96. id="rich-text-toggle-tooltip"
  97. description={t('toolbar_change_editor_mode')}
  98. overlayProps={{ placement: 'bottom' }}
  99. tooltipProps={{ className: 'tooltip-wide' }}
  100. >
  101. {toggle}
  102. </OLTooltip>
  103. )
  104. }
  105. export default memo(EditorSwitch)