RawLayout.tsx 1.6 KB

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