main-layout.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { Panel, PanelGroup } from 'react-resizable-panels'
  2. import { ReactNode, useState } from 'react'
  3. import { HorizontalResizeHandle } from '../resize/horizontal-resize-handle'
  4. import useFixedSizeColumn from '@/features/ide-react/hooks/use-fixed-size-column'
  5. import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel'
  6. import classNames from 'classnames'
  7. const CHAT_DEFAULT_SIZE = 20
  8. type PageProps = {
  9. headerContent: ReactNode
  10. chatContent: ReactNode
  11. mainContent: ReactNode
  12. chatIsOpen: boolean
  13. shouldPersistLayout: boolean
  14. }
  15. // The main area below the header is split into two: the main content and chat.
  16. // The reason for not splitting the left column containing the file tree and
  17. // outline here is that the history view has its own file tree, so it is more
  18. // convenient to replace the whole of the main content when in history view.
  19. export default function MainLayout({
  20. headerContent,
  21. chatContent,
  22. mainContent,
  23. chatIsOpen,
  24. shouldPersistLayout,
  25. }: PageProps) {
  26. const { fixedPanelRef: chatPanelRef, handleLayout } = useFixedSizeColumn(
  27. CHAT_DEFAULT_SIZE,
  28. chatIsOpen
  29. )
  30. useCollapsiblePanel(chatIsOpen, chatPanelRef)
  31. const [resizing, setResizing] = useState(false)
  32. return (
  33. <div className="ide-react-main">
  34. {headerContent}
  35. <div className="ide-react-body">
  36. <PanelGroup
  37. autoSaveId={shouldPersistLayout ? 'ide-react-chat-layout' : undefined}
  38. direction="horizontal"
  39. onLayout={handleLayout}
  40. className={classNames({
  41. 'ide-react-main-resizing': resizing,
  42. })}
  43. >
  44. <Panel id="main" order={1}>
  45. {mainContent}
  46. </Panel>
  47. {chatIsOpen ? (
  48. <>
  49. <HorizontalResizeHandle onDragging={setResizing} />
  50. <Panel
  51. ref={chatPanelRef}
  52. id="chat"
  53. order={2}
  54. defaultSize={CHAT_DEFAULT_SIZE}
  55. minSize={5}
  56. collapsible
  57. >
  58. {chatContent}
  59. </Panel>
  60. </>
  61. ) : null}
  62. </PanelGroup>
  63. </div>
  64. </div>
  65. )
  66. }