RawLayout.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import type { ReactNode } from 'react';
  2. import React, { useState } from 'react';
  3. import type { ColorScheme } from '@growi/core';
  4. import Head from 'next/head';
  5. import { ToastContainer } from 'react-toastify';
  6. import { useIsomorphicLayoutEffect } from 'usehooks-ts';
  7. import { useNextThemes, NextThemesProvider } from '~/stores/use-next-themes';
  8. import loggerFactory from '~/utils/logger';
  9. import styles from './RawLayout.module.scss';
  10. const toastContainerClass = styles['grw-toast-container'] ?? '';
  11. const logger = loggerFactory('growi:cli:RawLayout');
  12. type Props = {
  13. className?: string,
  14. children?: ReactNode,
  15. }
  16. export const RawLayout = ({ children, className }: Props): JSX.Element => {
  17. const classNames: string[] = ['layout-root', 'growi'];
  18. if (className != null) {
  19. classNames.push(className);
  20. }
  21. // get color scheme from next-themes
  22. const { resolvedTheme, resolvedThemeByAttributes } = useNextThemes();
  23. const [colorScheme, setColorScheme] = useState<ColorScheme|undefined>(undefined);
  24. // set colorScheme in CSR
  25. useIsomorphicLayoutEffect(() => {
  26. setColorScheme(resolvedTheme ?? resolvedThemeByAttributes);
  27. }, [resolvedTheme, resolvedThemeByAttributes]);
  28. return (
  29. <>
  30. <Head>
  31. <meta charSet="utf-8" />
  32. <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  33. </Head>
  34. <NextThemesProvider>
  35. <div className={classNames.join(' ')}>
  36. {children}
  37. <ToastContainer className={toastContainerClass} theme={colorScheme} />
  38. </div>
  39. </NextThemesProvider>
  40. </>
  41. );
  42. };