main-layout.tsx 1.9 KB

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