xref: /expo/docs/ui/components/Layout/Layout.tsx (revision 9de0c686)
134b42efdSBartosz Kaszubowskiimport { css, Global } from '@emotion/react';
2d5517a1fSBartosz Kaszubowskiimport { SerializedStyles } from '@emotion/serialize';
3f4b1168bSBartosz Kaszubowskiimport { theme } from '@expo/styleguide';
4f4b1168bSBartosz Kaszubowskiimport { breakpoints, spacing } from '@expo/styleguide-base';
5f4b1168bSBartosz Kaszubowskiimport { PropsWithChildren, ReactNode } from 'react';
6d5113603SCedric van Putten
7d04fd43fSBartosz Kaszubowskiimport { Sidebar } from '../Sidebar';
8d04fd43fSBartosz Kaszubowski
934b42efdSBartosz Kaszubowskiimport { Header } from '~/ui/components/Header';
1034b42efdSBartosz Kaszubowskiimport { LayoutScroll } from '~/ui/components/Layout';
11d5113603SCedric van Putten
12d5113603SCedric van Puttentype LayoutProps = PropsWithChildren<{
13d5517a1fSBartosz Kaszubowski  /**
14d5517a1fSBartosz Kaszubowski   * The content within the top bar that spans the columns.
15d5517a1fSBartosz Kaszubowski   */
1634b42efdSBartosz Kaszubowski  header?: ReactNode;
17d5517a1fSBartosz Kaszubowski  /**
18d5517a1fSBartosz Kaszubowski   * The content within the left column.
19d5517a1fSBartosz Kaszubowski   */
20d5113603SCedric van Putten  navigation?: ReactNode;
21d5517a1fSBartosz Kaszubowski  /**
22d5517a1fSBartosz Kaszubowski   * The content within the right column.
23d5517a1fSBartosz Kaszubowski   */
24d5113603SCedric van Putten  sidebar?: ReactNode;
25d5517a1fSBartosz Kaszubowski  /**
26d5517a1fSBartosz Kaszubowski   * Custom CSS for the whole layout.
27d5517a1fSBartosz Kaszubowski   */
28d5517a1fSBartosz Kaszubowski  cssLayout?: SerializedStyles;
29d5517a1fSBartosz Kaszubowski  /**
30d5517a1fSBartosz Kaszubowski   * Custom CSS for the main content wrapper.
31d5517a1fSBartosz Kaszubowski   */
32d5517a1fSBartosz Kaszubowski  cssContent?: SerializedStyles;
33d5113603SCedric van Putten}>;
34d5113603SCedric van Putten
35d5517a1fSBartosz Kaszubowskiexport const Layout = ({
36d04fd43fSBartosz Kaszubowski  // note(simek): stub props for now, until we don't use new Layout
37d04fd43fSBartosz Kaszubowski  header = (
38d04fd43fSBartosz Kaszubowski    <Header
39d04fd43fSBartosz Kaszubowski      sidebar={<Sidebar />}
40*9de0c686SAman Mittal      sidebarActiveGroup="home"
41d04fd43fSBartosz Kaszubowski      isMobileMenuVisible={false}
42d04fd43fSBartosz Kaszubowski      setMobileMenuVisible={() => undefined}
43d04fd43fSBartosz Kaszubowski    />
44d04fd43fSBartosz Kaszubowski  ),
45d5517a1fSBartosz Kaszubowski  navigation,
46d5517a1fSBartosz Kaszubowski  sidebar,
47d5517a1fSBartosz Kaszubowski  children,
48d5517a1fSBartosz Kaszubowski  cssLayout = undefined,
49d5517a1fSBartosz Kaszubowski  cssContent = undefined,
50d5517a1fSBartosz Kaszubowski}: LayoutProps) => (
5134b42efdSBartosz Kaszubowski  <>
5234b42efdSBartosz Kaszubowski    <Global
5334b42efdSBartosz Kaszubowski      styles={css({
5434b42efdSBartosz Kaszubowski        // Ensure correct background for Overscroll
5514c78e61SJon Samp        'body.dark-theme': {
5634b42efdSBartosz Kaszubowski          backgroundColor: theme.background.screen,
5734b42efdSBartosz Kaszubowski        },
5834b42efdSBartosz Kaszubowski      })}
5934b42efdSBartosz Kaszubowski    />
6034b42efdSBartosz Kaszubowski    <header css={headerStyle}>{header}</header>
61d5517a1fSBartosz Kaszubowski    <main css={[layoutStyle, cssLayout]}>
6234b42efdSBartosz Kaszubowski      {navigation && <nav css={navigationStyle}>{navigation}</nav>}
63d5113603SCedric van Putten      <LayoutScroll>
64d5517a1fSBartosz Kaszubowski        <article css={[innerContentStyle, cssContent]}>{children}</article>
65d5113603SCedric van Putten      </LayoutScroll>
6634b42efdSBartosz Kaszubowski      {sidebar && <aside css={asideStyle}>{sidebar}</aside>}
6734b42efdSBartosz Kaszubowski    </main>
6834b42efdSBartosz Kaszubowski  </>
69d5113603SCedric van Putten);
7034b42efdSBartosz Kaszubowski
7134b42efdSBartosz Kaszubowskiconst HEADER_HEIGHT = 60;
72d5113603SCedric van Putten
73d5113603SCedric van Puttenconst layoutStyle = css({
7434b42efdSBartosz Kaszubowski  display: 'flex',
7534b42efdSBartosz Kaszubowski  alignItems: 'stretch',
7634b42efdSBartosz Kaszubowski  maxHeight: `calc(100vh - ${HEADER_HEIGHT}px)`,
7734b42efdSBartosz Kaszubowski  marginTop: HEADER_HEIGHT,
783784f9b9SCedric van Putten  backgroundColor: theme.background.default,
7914c78e61SJon Samp  '.dark-theme &': {
803784f9b9SCedric van Putten    backgroundColor: theme.background.screen,
813784f9b9SCedric van Putten  },
8234b42efdSBartosz Kaszubowski  [`@media screen and (max-width: ${breakpoints.medium}px)`]: {
8334b42efdSBartosz Kaszubowski    // Ditch inner scroll on mobile, which results in weird bugs
8434b42efdSBartosz Kaszubowski    maxHeight: 'none',
8534b42efdSBartosz Kaszubowski  },
86d5113603SCedric van Putten});
87d5113603SCedric van Putten
8834b42efdSBartosz Kaszubowskiconst headerStyle = css({
8934b42efdSBartosz Kaszubowski  position: 'fixed',
9034b42efdSBartosz Kaszubowski  top: 0,
9134b42efdSBartosz Kaszubowski  width: '100%',
9234b42efdSBartosz Kaszubowski  height: HEADER_HEIGHT,
9334b42efdSBartosz Kaszubowski  zIndex: 100,
9434b42efdSBartosz Kaszubowski});
95d5113603SCedric van Putten
96d5113603SCedric van Puttenconst navigationStyle = css({
9734b42efdSBartosz Kaszubowski  flexBasis: 256,
9834b42efdSBartosz Kaszubowski  [`@media screen and (max-width: ${breakpoints.medium}px)`]: {
99d5113603SCedric van Putten    display: 'none',
100d5113603SCedric van Putten  },
101d5113603SCedric van Putten});
102d5113603SCedric van Putten
103d5113603SCedric van Puttenconst innerContentStyle = css({
104d5113603SCedric van Putten  margin: '0 auto',
105d5517a1fSBartosz Kaszubowski  minHeight: `calc(100vh - ${HEADER_HEIGHT}px)`,
106d5113603SCedric van Putten  maxWidth: breakpoints.large,
10734b42efdSBartosz Kaszubowski  padding: `${spacing[8]}px ${spacing[4]}px`,
108d5113603SCedric van Putten});
109d5113603SCedric van Putten
11034b42efdSBartosz Kaszubowskiconst asideStyle = css({
11134b42efdSBartosz Kaszubowski  flexBasis: 288,
112d5113603SCedric van Putten  [`@media screen and (max-width: ${breakpoints.medium}px)`]: {
113d5113603SCedric van Putten    display: 'none',
114d5113603SCedric van Putten  },
115d5113603SCedric van Putten});
116