editor-switch.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import { ChangeEvent, FC, 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 isValidTeXFile from '../../../main/is-valid-tex-file'
  6. import { useTranslation } from 'react-i18next'
  7. import { PromotionOverlay } from './table-generator/promotion/popover'
  8. import { FeedbackBadge } from '@/shared/components/feedback-badge'
  9. function EditorSwitch() {
  10. const { t } = useTranslation()
  11. const [visual, setVisual] = useScopeValue('editor.showVisual')
  12. const [docName] = useScopeValue('editor.open_doc_name')
  13. const richTextAvailable = isValidTeXFile(docName)
  14. const handleChange = useCallback(
  15. event => {
  16. const editorType = event.target.value
  17. switch (editorType) {
  18. case 'cm6':
  19. setVisual(false)
  20. break
  21. case 'rich-text':
  22. setVisual(true)
  23. break
  24. }
  25. sendMB('editor-switch-change', { editorType })
  26. },
  27. [setVisual]
  28. )
  29. return (
  30. <div className="editor-toggle-switch">
  31. <fieldset className="toggle-switch">
  32. <legend className="sr-only">Editor mode.</legend>
  33. <input
  34. type="radio"
  35. name="editor"
  36. value="cm6"
  37. id="editor-switch-cm6"
  38. className="toggle-switch-input"
  39. checked={!richTextAvailable || !visual}
  40. onChange={handleChange}
  41. />
  42. <label htmlFor="editor-switch-cm6" className="toggle-switch-label">
  43. <span>{t('code_editor')}</span>
  44. </label>
  45. <RichTextToggle
  46. checked={richTextAvailable && visual}
  47. disabled={!richTextAvailable}
  48. handleChange={handleChange}
  49. />
  50. </fieldset>
  51. {richTextAvailable && visual && (
  52. <FeedbackBadge
  53. id="visual-editor-feedback"
  54. url="https://forms.gle/AUqHmKNiEH3DRniPA"
  55. text={<VisualEditorFeedbackContent />}
  56. />
  57. )}
  58. </div>
  59. )
  60. }
  61. const VisualEditorFeedbackContent = () => (
  62. <>
  63. We have a new Visual Editor!
  64. <br />
  65. Click to give feedback
  66. </>
  67. )
  68. const RichTextToggle: FC<{
  69. checked: boolean
  70. disabled: boolean
  71. handleChange: (event: ChangeEvent<HTMLInputElement>) => void
  72. }> = ({ checked, disabled, handleChange }) => {
  73. const { t } = useTranslation()
  74. const toggle = (
  75. <span>
  76. <input
  77. type="radio"
  78. name="editor"
  79. value="rich-text"
  80. id="editor-switch-rich-text"
  81. className="toggle-switch-input"
  82. checked={checked}
  83. onChange={handleChange}
  84. disabled={disabled}
  85. />
  86. <label htmlFor="editor-switch-rich-text" className="toggle-switch-label">
  87. <span>{t('visual_editor')}</span>
  88. </label>
  89. </span>
  90. )
  91. if (disabled) {
  92. return (
  93. <Tooltip
  94. description={t('visual_editor_is_only_available_for_tex_files')}
  95. id="rich-text-toggle-tooltip"
  96. overlayProps={{ placement: 'bottom' }}
  97. tooltipProps={{ className: 'tooltip-wide' }}
  98. >
  99. {toggle}
  100. </Tooltip>
  101. )
  102. }
  103. return <PromotionOverlay>{toggle}</PromotionOverlay>
  104. }
  105. export default memo(EditorSwitch)