two-column-main-content.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { ReactNode, useEffect, useState } from 'react'
  2. import { Panel, PanelGroup } from 'react-resizable-panels'
  3. import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/horizontal-resize-handle'
  4. import { useTranslation } from 'react-i18next'
  5. import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler'
  6. import useFixedSizeColumn from '@/features/ide-react/hooks/use-fixed-size-column'
  7. import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel'
  8. import classNames from 'classnames'
  9. type TwoColumnMainContentProps = {
  10. leftColumnId: string
  11. leftColumnContent: ReactNode
  12. leftColumnDefaultSize: number
  13. setLeftColumnDefaultSize: React.Dispatch<React.SetStateAction<number>>
  14. rightColumnContent: ReactNode
  15. leftColumnIsOpen: boolean
  16. setLeftColumnIsOpen: (
  17. leftColumnIsOpen: TwoColumnMainContentProps['leftColumnIsOpen']
  18. ) => void
  19. shouldPersistLayout?: boolean
  20. }
  21. export default function TwoColumnMainContent({
  22. leftColumnId,
  23. leftColumnContent,
  24. leftColumnDefaultSize,
  25. setLeftColumnDefaultSize,
  26. rightColumnContent,
  27. leftColumnIsOpen,
  28. setLeftColumnIsOpen,
  29. shouldPersistLayout = false,
  30. }: TwoColumnMainContentProps) {
  31. const { t } = useTranslation()
  32. const {
  33. fixedPanelRef: leftColumnPanelRef,
  34. fixedPanelWidthRef: leftColumnWidthRef,
  35. handleLayout,
  36. } = useFixedSizeColumn(leftColumnDefaultSize, leftColumnIsOpen)
  37. useCollapsiblePanel(leftColumnIsOpen, leftColumnPanelRef)
  38. const [resizing, setResizing] = useState(false)
  39. // Update the left column default size on unmount rather than doing it on
  40. // every resize, which causes ResizeObserver errors
  41. useEffect(() => {
  42. if (leftColumnWidthRef.current) {
  43. setLeftColumnDefaultSize(leftColumnWidthRef.current.size)
  44. }
  45. }, [leftColumnWidthRef, setLeftColumnDefaultSize])
  46. return (
  47. <PanelGroup
  48. autoSaveId={
  49. shouldPersistLayout ? 'ide-react-main-content-layout' : undefined
  50. }
  51. direction="horizontal"
  52. onLayout={handleLayout}
  53. className={classNames({
  54. 'ide-react-main-content-resizing': resizing,
  55. })}
  56. >
  57. <Panel
  58. ref={leftColumnPanelRef}
  59. defaultSize={leftColumnDefaultSize}
  60. minSize={5}
  61. collapsible
  62. onCollapse={collapsed => setLeftColumnIsOpen(!collapsed)}
  63. >
  64. {leftColumnContent}
  65. </Panel>
  66. <HorizontalResizeHandle
  67. onDoubleClick={() => setLeftColumnIsOpen(!leftColumnIsOpen)}
  68. resizable={leftColumnIsOpen}
  69. onDragging={setResizing}
  70. >
  71. <HorizontalToggler
  72. id={leftColumnId}
  73. togglerType="west"
  74. isOpen={leftColumnIsOpen}
  75. setIsOpen={setLeftColumnIsOpen}
  76. tooltipWhenOpen={t('tooltip_hide_filetree')}
  77. tooltipWhenClosed={t('tooltip_show_filetree')}
  78. />
  79. </HorizontalResizeHandle>
  80. <Panel className="ide-react-panel">{rightColumnContent}</Panel>
  81. </PanelGroup>
  82. )
  83. }