editor-and-pdf.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { ReactNode, useRef, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import {
  4. ImperativePanelHandle,
  5. Panel,
  6. PanelGroup,
  7. } from 'react-resizable-panels'
  8. import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/horizontal-resize-handle'
  9. import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler'
  10. import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel'
  11. import { useLayoutContext } from '@/shared/context/layout-context'
  12. import PdfPreview from '@/features/pdf-preview/components/pdf-preview'
  13. import { DefaultSynctexControl } from '@/features/pdf-preview/components/detach-synctex-control'
  14. import classnames from 'classnames'
  15. export type EditorProps = {
  16. shouldPersistLayout?: boolean
  17. editorContent: ReactNode
  18. }
  19. export default function EditorAndPdf({
  20. shouldPersistLayout = false,
  21. editorContent,
  22. }: EditorProps) {
  23. const { t } = useTranslation()
  24. const { view, pdfLayout, changeLayout, detachRole, reattach } =
  25. useLayoutContext()
  26. const [resizing, setResizing] = useState(false)
  27. const pdfPanelRef = useRef<ImperativePanelHandle>(null)
  28. const isDualPane = pdfLayout === 'sideBySide'
  29. const editorIsVisible = isDualPane || view === 'editor' || view === 'file'
  30. const pdfIsOpen = isDualPane || view === 'pdf'
  31. useCollapsiblePanel(pdfIsOpen, pdfPanelRef)
  32. const historyIsOpen = view === 'history'
  33. function setPdfIsOpen(isOpen: boolean) {
  34. if (isOpen) {
  35. if (detachRole === 'detacher') {
  36. reattach()
  37. }
  38. changeLayout('sideBySide')
  39. } else {
  40. changeLayout('flat', 'editor')
  41. }
  42. }
  43. return (
  44. <PanelGroup
  45. autoSaveId={
  46. shouldPersistLayout ? 'ide-react-editor-and-pdf-layout' : undefined
  47. }
  48. direction="horizontal"
  49. className={classnames('ide-react-editor-and-pdf', {
  50. hide: historyIsOpen,
  51. 'ide-react-editor-and-pdf-resizing': resizing,
  52. })}
  53. >
  54. {editorIsVisible ? (
  55. <Panel
  56. id="editor"
  57. order={1}
  58. defaultSize={50}
  59. className="ide-react-panel"
  60. >
  61. <div className="ide-react-editor-content full-size">
  62. {editorContent}
  63. </div>
  64. </Panel>
  65. ) : null}
  66. <HorizontalResizeHandle
  67. resizable={isDualPane}
  68. onDoubleClick={() => setPdfIsOpen(!pdfIsOpen)}
  69. onDragging={setResizing}
  70. >
  71. <HorizontalToggler
  72. id="editor-pdf"
  73. togglerType="east"
  74. isOpen={pdfIsOpen}
  75. setIsOpen={setPdfIsOpen}
  76. tooltipWhenOpen={t('tooltip_hide_pdf')}
  77. tooltipWhenClosed={t('tooltip_show_pdf')}
  78. />
  79. {isDualPane ? (
  80. <div className="synctex-controls">
  81. <DefaultSynctexControl />
  82. </div>
  83. ) : null}
  84. </HorizontalResizeHandle>
  85. <Panel
  86. ref={pdfPanelRef}
  87. id="pdf"
  88. order={2}
  89. defaultSize={50}
  90. minSize={5}
  91. collapsible
  92. onCollapse={collapsed => setPdfIsOpen(!collapsed)}
  93. className="ide-react-panel"
  94. >
  95. {pdfIsOpen || resizing ? <PdfPreview /> : null}
  96. </Panel>
  97. </PanelGroup>
  98. )
  99. }