Switch to infinite scroll (Full book)

Appshell

Appshell is a mega layout component that manages:

  • The header on-top of the page, also called the banner.
  • The main section, below the header
  • The left-side navbar and the right-side aside (if applicable)

synopsis

<AppShell header={{}} navbar={{}} aside={{}} footer={{}}>
    <AppShell.Header />
    <AppShell.Navbar />
    <AppShell.Aside />
    <AppShell.Main />
    <AppShell.Footer />
</AppShell>

Note: the configuration objects are set on AppShell as props. They are required when we use the corresponding component (except for AppShell.Main).

header

The header usually manages:

  • the burger button
  • the logo
  • (optional) the dark mode toggle, the user button, a set of links.
<AppShell.Header>
    <Burger opened={opened} onClick={toggle} hiddenFrom="sm" />
</AppShell.Header>

configure the header

We commonly set the height:

<AppShell header={{ height: 60 }} /* ... */ />

navbar

<AppShell navbar={{}} /* ... */ />

The navbar stands on the left side. On mobile, it only appears in a transient fashion, and is collapsed by default. On desktop it is commonly always-on, though we sometimes offer to collapse it too.

We control the collapsing state with collapsed, and the breakpoint from mobile to desktop with breakpoint:

  • collapsed receives up to two boolean state variables: one for mobile and one for desktop. Most of the time, we only use the mobile state variable, and keep desktop always opened.
  • breakpoint controls when the collapse logic switches from mobile to desktop, aka when to use the mobile opened state versus the desktop opened state.
  • The burger button is responsible for toggling the state on and off:
const [mobileOpened, { toggle: toggleMobile }] = useDisclosure()

return (
    <AppShell
        navbar={{
            collapsed: { mobile: !opened },
            breakpoint: "sm",
        }}
    >
        <AppShell.Header>
            <Burger opened={opened} onClick={toggle} hiddenFrom="sm" />
        </AppShell.Header>
    </AppShell>
)

We hide the mobile burger on desktop with hiddenFrom since it only controls the mobile state.

supporting collapse on desktop

If we support desktop collapse, we provide a separate burger button controlling the desktop state.

We use an additional boolean state variable, and provide it to collapsed.

Note: the desktop burger button commonly keeps the same appearance instead of showing a close icon, since we are not really closing anything, contrary to mobile.

We display it only on desktop with visibleFrom:

const [mobileOpened, { toggle: toggleMobile }] = useDisclosure(false)
const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true)

return (
    <AppShell
        navbar={{
            collapsed: { mobile: !mobileOpened, desktop: !desktopOpened },
            breakpoint: "sm",
        }}
    >
        <AppShell.Header>
            {/* mobile */}
            <Burger opened={mobileOpened} onClick={toggleMobile} hiddenFrom="sm" />
            {/* desktop */}
            <Burger opened={false} onClick={toggleDesktop} visibleFrom="sm" />
        </AppShell.Header>
    </AppShell>
)

navbar: desktop width

In mobile, the opened navbar is always full screen.

On desktop, we control the width with width. We provide an immediate value or an object with two or more values:

navbar={{ width: 300, /* ... */ }}

navbar: top and bottom sections

We can split the navbar into AppShell.Sections. One of them can grow.

<AppShell.Navbar>
    <AppShell.Section grow> </AppShell.Section>
    <AppShell.Section> </AppShell.Section>
</AppShell.Navbar>

Appshell.Main

The container for the main panel.

Its background defaults to the body's background color (--mantine-color-body):

  • In light mode, It is white. We can pick a light gray background such as gray.1, so that inner containers may stand out as white.
  • In dark mode, it is dark.7. We can pick dark.8 so that inner elements may standout as dark.7.
const backgroundColor = colorScheme === "dark" ? "dark.8" : "gray.1"
earlymorning logo

Appshell

Appshell is a mega layout component that manages:

  • The header on-top of the page, also called the banner.
  • The main section, below the header
  • The left-side navbar and the right-side aside (if applicable)

synopsis

<AppShell header={{}} navbar={{}} aside={{}} footer={{}}>
    <AppShell.Header />
    <AppShell.Navbar />
    <AppShell.Aside />
    <AppShell.Main />
    <AppShell.Footer />
</AppShell>

Note: the configuration objects are set on AppShell as props. They are required when we use the corresponding component (except for AppShell.Main).

header

The header usually manages:

  • the burger button
  • the logo
  • (optional) the dark mode toggle, the user button, a set of links.
<AppShell.Header>
    <Burger opened={opened} onClick={toggle} hiddenFrom="sm" />
</AppShell.Header>

configure the header

We commonly set the height:

<AppShell header={{ height: 60 }} /* ... */ />

navbar

<AppShell navbar={{}} /* ... */ />

The navbar stands on the left side. On mobile, it only appears in a transient fashion, and is collapsed by default. On desktop it is commonly always-on, though we sometimes offer to collapse it too.

We control the collapsing state with collapsed, and the breakpoint from mobile to desktop with breakpoint:

  • collapsed receives up to two boolean state variables: one for mobile and one for desktop. Most of the time, we only use the mobile state variable, and keep desktop always opened.
  • breakpoint controls when the collapse logic switches from mobile to desktop, aka when to use the mobile opened state versus the desktop opened state.
  • The burger button is responsible for toggling the state on and off:
const [mobileOpened, { toggle: toggleMobile }] = useDisclosure()

return (
    <AppShell
        navbar={{
            collapsed: { mobile: !opened },
            breakpoint: "sm",
        }}
    >
        <AppShell.Header>
            <Burger opened={opened} onClick={toggle} hiddenFrom="sm" />
        </AppShell.Header>
    </AppShell>
)

We hide the mobile burger on desktop with hiddenFrom since it only controls the mobile state.

supporting collapse on desktop

If we support desktop collapse, we provide a separate burger button controlling the desktop state.

We use an additional boolean state variable, and provide it to collapsed.

Note: the desktop burger button commonly keeps the same appearance instead of showing a close icon, since we are not really closing anything, contrary to mobile.

We display it only on desktop with visibleFrom:

const [mobileOpened, { toggle: toggleMobile }] = useDisclosure(false)
const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true)

return (
    <AppShell
        navbar={{
            collapsed: { mobile: !mobileOpened, desktop: !desktopOpened },
            breakpoint: "sm",
        }}
    >
        <AppShell.Header>
            {/* mobile */}
            <Burger opened={mobileOpened} onClick={toggleMobile} hiddenFrom="sm" />
            {/* desktop */}
            <Burger opened={false} onClick={toggleDesktop} visibleFrom="sm" />
        </AppShell.Header>
    </AppShell>
)

navbar: desktop width

In mobile, the opened navbar is always full screen.

On desktop, we control the width with width. We provide an immediate value or an object with two or more values:

navbar={{ width: 300, /* ... */ }}

navbar: top and bottom sections

We can split the navbar into AppShell.Sections. One of them can grow.

<AppShell.Navbar>
    <AppShell.Section grow> </AppShell.Section>
    <AppShell.Section> </AppShell.Section>
</AppShell.Navbar>

Appshell.Main

The container for the main panel.

Its background defaults to the body's background color (--mantine-color-body):

  • In light mode, It is white. We can pick a light gray background such as gray.1, so that inner containers may stand out as white.
  • In dark mode, it is dark.7. We can pick dark.8 so that inner elements may standout as dark.7.
const backgroundColor = colorScheme === "dark" ? "dark.8" : "gray.1"