Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add persistent app layouts to template #245

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions packages/create-bison-app/template/components/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,21 @@ export function Nav() {

<MenuList width="full">
<MenuItem>
<Link href="/">Link 1</Link>
<NextLink href="/page1" passHref>
<Link>Link 1</Link>
</NextLink>
</MenuItem>

<MenuItem>
<Link href="/">Link 2</Link>
<NextLink href="/page1" passHref>
<Link>Link 2</Link>
</NextLink>
</MenuItem>

<MenuItem>
<Link href="/">Link 3</Link>
<NextLink href="/page3" passHref>
<Link>Link 3</Link>
</NextLink>
</MenuItem>

<MenuItem>
Expand All @@ -43,10 +49,18 @@ export function Nav() {
</Menu>
) : (
<Stack as="nav" direction="row" ml="auto" alignItems="center" fontSize="md" spacing={8}>
<Link href="/">Link 1</Link>
<NextLink href="/page1" passHref>
<Link>Link 1</Link>
</NextLink>

<NextLink href="/page2" passHref>
<Link>Link 2</Link>
</NextLink>

<NextLink href="/page3" passHref>
<Link>Link 3</Link>
</NextLink>

<Link href="/#features">Link 2</Link>
<Link href="/#tech">Link 3</Link>
<Link href="https://github.com/echobind/" isExternal>
External
</Link>
Expand Down
13 changes: 13 additions & 0 deletions packages/create-bison-app/template/layouts/CenteredPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Flex } from '@chakra-ui/react';

export type CenteredPageLayoutProps = {
children: React.ReactNode;
};

export const CenteredPageLayout = ({ children }: CenteredPageLayoutProps) => (
<Flex direction="column" minH="100vh" bg="pink" align="center" justify="center">
{children}
</Flex>
);

export const getLayout = (page: any) => <CenteredPageLayout>{page}</CenteredPageLayout>;
4 changes: 4 additions & 0 deletions packages/create-bison-app/template/layouts/LoggedIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Nav } from '../components/Nav';
import { useAuth } from '../context/auth';
import { Footer } from '../components/Footer';

import { getLayout } from '../layouts/CenteredPageLayout';

interface Props {
children: React.ReactNode;
}
Expand Down Expand Up @@ -48,3 +50,5 @@ export function LoggedInLayout({ children }: Props) {
</Flex>
);
}

LoggedInLayout.getLayout = getLayout;
4 changes: 4 additions & 0 deletions packages/create-bison-app/template/layouts/LoggedOut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ButtonLink } from '../components/Link';
import { Logo } from '../components/Logo';
import { Footer } from '../components/Footer';

import { getLayout } from '../layouts/CenteredPageLayout';

interface Props {
children: React.ReactNode;
}
Expand All @@ -30,3 +32,5 @@ export function LoggedOutLayout({ children }: Props) {
</Flex>
);
}

LoggedOutLayout.getLayout = getLayout;
21 changes: 16 additions & 5 deletions packages/create-bison-app/template/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import React from 'react';
import type { AppProps } from 'next/app';
import { NextComponentType } from 'next';
import { AppProps as NextAppProps } from 'next/app';
import dynamic from 'next/dynamic';

import { AllProviders } from '../components/AllProviders';
import { useAuth } from '../context/auth';

export type BisonComponentType = NextComponentType & {
getLayout?: (page: () => React.ReactNode) => React.ReactNode;
};

export type BisonAppProps = NextAppProps & {
Component: BisonComponentType;
};

/**
* Dynamically load layouts. This codesplits and prevents code from the logged in layout from being
* included in the bundle if we're rendering the logged out layout.
Expand All @@ -30,12 +39,14 @@ function AppWithAuth({ children }: { children: React.ReactNode }) {
);
}

function App({ pageProps, Component }: AppProps) {
function App({ pageProps, Component }: BisonAppProps) {
// Look for a static getLayout method on the component, and use it if it exists. This allows us to have
// persistent elements on the page that don't re-render as we navigate if they don't need to.
const getLayout = Component.getLayout || ((page: any) => page);

return (
<AllProviders>
<AppWithAuth>
<Component {...pageProps} />
</AppWithAuth>
<AppWithAuth>{getLayout(<Component {...pageProps} />)}</AppWithAuth>
</AllProviders>
);
}
Expand Down
13 changes: 13 additions & 0 deletions packages/create-bison-app/template/pages/page1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Heading } from '@chakra-ui/react';

import { getLayout } from '../layouts/CenteredPageLayout';

export default function Page1() {
return (
<>
<Heading size="lg">Page 1</Heading>
</>
);
}

Page1.getLayout = getLayout;
13 changes: 13 additions & 0 deletions packages/create-bison-app/template/pages/page2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Heading } from '@chakra-ui/react';

import { getLayout } from '../layouts/CenteredPageLayout';

export default function Page2() {
return (
<>
<Heading size="lg">Page 2</Heading>
</>
);
}

Page2.getLayout = getLayout;
13 changes: 13 additions & 0 deletions packages/create-bison-app/template/pages/page3.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Heading } from '@chakra-ui/react';

import { getLayout } from '../layouts/CenteredPageLayout';

export default function Page3() {
return (
<>
<Heading size="lg">Page 3</Heading>
</>
);
}

Page3.getLayout = getLayout;