editor-switch.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { memo, useCallback } from 'react'
  2. import useScopeValue from '../../../shared/hooks/use-scope-value'
  3. import Tooltip from '../../../shared/components/tooltip'
  4. import { sendMB } from '../../../infrastructure/event-tracking'
  5. import getMeta from '../../../utils/meta'
  6. import SplitTestBadge from '../../../shared/components/split-test-badge'
  7. function Badge() {
  8. const content = (
  9. <>
  10. Overleaf has upgraded the source editor. You can still use the old editor
  11. by selecting "Source (legacy)".
  12. <br />
  13. <br />
  14. Click to learn more and give feedback
  15. </>
  16. )
  17. return (
  18. <Tooltip
  19. id="editor-switch"
  20. description={content}
  21. overlayProps={{
  22. placement: 'bottom',
  23. delayHide: 100,
  24. }}
  25. tooltipProps={{ className: 'tooltip-wide' }}
  26. >
  27. <a
  28. href="https://forms.gle/GmSs6odZRKRp3VX98"
  29. target="_blank"
  30. rel="noopener noreferrer"
  31. className="badge info-badge"
  32. >
  33. <span className="sr-only">{content}</span>
  34. </a>
  35. </Tooltip>
  36. )
  37. }
  38. const showLegacySourceEditor: boolean = getMeta('ol-showLegacySourceEditor')
  39. function EditorSwitch() {
  40. const [newSourceEditor, setNewSourceEditor] = useScopeValue(
  41. 'editor.newSourceEditor'
  42. )
  43. const [richText, setRichText] = useScopeValue('editor.showRichText')
  44. const [visual, setVisual] = useScopeValue('editor.showVisual')
  45. const richTextOrVisual = richText || visual
  46. const handleChange = useCallback(
  47. event => {
  48. const editorType = event.target.value
  49. switch (editorType) {
  50. case 'ace':
  51. setRichText(false)
  52. setVisual(false)
  53. setNewSourceEditor(false)
  54. break
  55. case 'cm6':
  56. setRichText(false)
  57. setVisual(false)
  58. setNewSourceEditor(true)
  59. break
  60. case 'rich-text':
  61. if (getMeta('ol-richTextVariant') === 'cm6') {
  62. setRichText(false)
  63. setVisual(true)
  64. setNewSourceEditor(true)
  65. } else {
  66. setRichText(true)
  67. setVisual(false)
  68. }
  69. break
  70. }
  71. sendMB('editor-switch-change', { editorType })
  72. },
  73. [setRichText, setVisual, setNewSourceEditor]
  74. )
  75. return (
  76. <div className="editor-toggle-switch">
  77. {showLegacySourceEditor ? <Badge /> : null}
  78. <fieldset className="toggle-switch">
  79. <legend className="sr-only">Editor mode.</legend>
  80. <input
  81. type="radio"
  82. name="editor"
  83. value="cm6"
  84. id="editor-switch-cm6"
  85. className="toggle-switch-input"
  86. checked={!richTextOrVisual && !!newSourceEditor}
  87. onChange={handleChange}
  88. />
  89. <label htmlFor="editor-switch-cm6" className="toggle-switch-label">
  90. <span>Source</span>
  91. </label>
  92. {showLegacySourceEditor ? (
  93. <>
  94. <input
  95. type="radio"
  96. name="editor"
  97. value="ace"
  98. id="editor-switch-ace"
  99. className="toggle-switch-input"
  100. checked={!richTextOrVisual && !newSourceEditor}
  101. onChange={handleChange}
  102. />
  103. <label htmlFor="editor-switch-ace" className="toggle-switch-label">
  104. <span>Source (legacy)</span>
  105. </label>
  106. </>
  107. ) : null}
  108. <input
  109. type="radio"
  110. name="editor"
  111. value="rich-text"
  112. id="editor-switch-rich-text"
  113. className="toggle-switch-input"
  114. checked={!!richTextOrVisual}
  115. onChange={handleChange}
  116. />
  117. <label
  118. htmlFor="editor-switch-rich-text"
  119. className="toggle-switch-label"
  120. >
  121. <span>Rich Text</span>
  122. </label>
  123. </fieldset>
  124. {!!richTextOrVisual && (
  125. <SplitTestBadge splitTestName="rich-text" displayOnVariants={['cm6']} />
  126. )}
  127. </div>
  128. )
  129. }
  130. export default memo(EditorSwitch)