BasicLayout.tsx 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import React, { ReactNode } from 'react';
  2. import dynamic from 'next/dynamic';
  3. import { DndProvider } from 'react-dnd';
  4. import { HTML5Backend } from 'react-dnd-html5-backend';
  5. import { useIsContainerFluid } from '~/stores/context';
  6. import { useSWRxCurrentPage } from '~/stores/page';
  7. import { GrowiNavbar } from '../Navbar/GrowiNavbar';
  8. import Sidebar from '../Sidebar';
  9. import { RawLayout } from './RawLayout';
  10. import { useEditorMode } from '~/stores/ui';
  11. const AlertSiteUrlUndefined = dynamic(() => import('../AlertSiteUrlUndefined').then(mod => mod.AlertSiteUrlUndefined), { ssr: false });
  12. const HotkeysManager = dynamic(() => import('../Hotkeys/HotkeysManager'), { ssr: false });
  13. // const PageCreateModal = dynamic(() => import('../client/js/components/PageCreateModal'), { ssr: false });
  14. const GrowiNavbarBottom = dynamic(() => import('../Navbar/GrowiNavbarBottom').then(mod => mod.GrowiNavbarBottom), { ssr: false });
  15. const ShortcutsModal = dynamic(() => import('../ShortcutsModal'), { ssr: false });
  16. const SystemVersion = dynamic(() => import('../SystemVersion'), { ssr: false });
  17. // Page modals
  18. const PageCreateModal = dynamic(() => import('../PageCreateModal'), { ssr: false });
  19. const PageDuplicateModal = dynamic(() => import('../PageDuplicateModal'), { ssr: false });
  20. const PageDeleteModal = dynamic(() => import('../PageDeleteModal'), { ssr: false });
  21. const PageRenameModal = dynamic(() => import('../PageRenameModal'), { ssr: false });
  22. const PagePresentationModal = dynamic(() => import('../PagePresentationModal'), { ssr: false });
  23. const PageAccessoriesModal = dynamic(() => import('../PageAccessoriesModal'), { ssr: false });
  24. // Fab
  25. const Fab = dynamic(() => import('../Fab').then(mod => mod.Fab), { ssr: false });
  26. type Props = {
  27. children?: ReactNode
  28. }
  29. export const BasicLayout = ({ children }: Props): JSX.Element => {
  30. const { data: currentPage } = useSWRxCurrentPage(); // Only /page, /share
  31. const { data: dataIsContainerFluid } = useIsContainerFluid(); // Only /page, /share
  32. const { getClassNamesByEditorMode } = useEditorMode(); // Only /page
  33. // Only /page, /share
  34. const isContainerFluidEachPage = currentPage == null || !('expandContentWidth' in currentPage)
  35. ? null
  36. : currentPage.expandContentWidth;
  37. const isContainerFluidDefault = dataIsContainerFluid;
  38. const isContainerFluid = isContainerFluidEachPage ?? isContainerFluidDefault;
  39. // Only /page
  40. const classNames: string[] = [];
  41. const isSidebar = currentPage?.path === '/Sidebar';
  42. classNames.push(...getClassNamesByEditorMode(isSidebar));
  43. const myClassName = `${classNames.join(' ') ?? ''} ${isContainerFluid ? 'growi-layout-fluid' : ''}`;
  44. return (
  45. <RawLayout className={myClassName}>
  46. <DndProvider backend={HTML5Backend}>
  47. <GrowiNavbar />
  48. <div className="page-wrapper d-flex d-print-block">
  49. <div className="grw-sidebar-wrapper">
  50. <Sidebar />
  51. </div>
  52. <div className="flex-fill mw-0" style={{ position: 'relative' }}>
  53. <AlertSiteUrlUndefined />
  54. {children}
  55. </div>
  56. </div>
  57. <GrowiNavbarBottom />
  58. <PageCreateModal />
  59. <PageDuplicateModal />
  60. <PageDeleteModal />
  61. <PageRenameModal />
  62. <PageAccessoriesModal />
  63. </DndProvider>
  64. <PagePresentationModal />
  65. <HotkeysManager />
  66. <Fab />
  67. <ShortcutsModal />
  68. <SystemVersion showShortcutsButton />
  69. </RawLayout>
  70. );
  71. };