two-column-main-content.tsx 2.6 KB

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