A Material Design navigation drawer (pp_drawer/1) — a vertical panel,
persistent on large screens (lg: and up, pinned via sticky so it stays
in place as the page scrolls, with its own internal scroll if its content
is taller than the viewport) and toggled by a mobile drawer below that
breakpoint. Compose it with PhoenixPaper.List / PhoenixPaper.ListItem
for its contents.
The mobile toggle is pure CSS, no JS/LiveView required: pp_drawer/1
renders a visually hidden checkbox, and both the drawer panel and its
backdrop react to it via peer-checked:. pp_drawer_toggle/1 is just a
<label for={...}> pointing at that same checkbox — clicking any label
wired to a checkbox's id checks it natively, so the toggle button and the
drawer don't need to be DOM siblings, unlike most of this library's other
peer-*/has-[:checked]: tricks (see AGENTS.md).
<.pp_app_bar>
<:leading><.pp_drawer_toggle for="app-drawer" /></:leading>
My App
</.pp_app_bar>
<.pp_drawer id="app-drawer" color="primary">
<:header>My App</:header>
<.pp_list>
<.pp_list_item navigate={~p"/"} active={@current_path == "/"}>
<:leading><.pp_icon name="hero-home" /></:leading>
Home
</.pp_list_item>
<.pp_list_item navigate={~p"/settings"} active={@current_path == "/settings"}>
<:leading><.pp_icon name="hero-cog-6-tooth" /></:leading>
Settings
</.pp_list_item>
</.pp_list>
</.pp_drawer>pp_drawer_toggle/1 lives here rather than its own module because it only
makes sense paired with a pp_drawer/1 (see AGENTS.md, "Component
conventions").
color
Defaults to "surface" (the original plain white/dark-surface look,
unchanged from before this attr existed). "primary"/"secondary"/
"tertiary" paint the whole panel that brand color — including its
nested PhoenixPaper.List/PhoenixPaper.ListItem/
PhoenixPaper.ListSubheader/PhoenixPaper.Divider content, which are
normally styled for a neutral surface background. There's no prop on
those components for "the color of my container" (same "no cascading"
limitation ButtonGroup/Tabs/AppBar already document), so instead
pp_drawer/1 reaches into them with a handful of [&_[data-pp-component=...]]
compound selectors — the same technique (and the same data-pp-component
attribute) Tabs's variant="full_width" already uses to reach its
child Tabs, just applied to more targets here. This is a real,
intentional exception to "components don't reach into each other" for
the one specific case where getting it wrong isn't a style mismatch but
actual illegibility: ListItem's active-item highlight
(bg-pp-primary/10) mixed with a color="primary" drawer background is
the exact same color layered on itself, which is mathematically
invisible, not just low-contrast — found and fixed by actually
screenshotting a colored drawer with an active nav item, not by
reasoning about it in the abstract. ListItem's active attr sets
aria-current="page" specifically so this selector has something stable
to target (see its moduledoc) — without that attribute there'd be no way
to tell an active item from an inactive one from CSS alone.
Summary
Functions
Renders a navigation drawer. See the module doc.
A hamburger button that toggles the pp_drawer/1 with the given for id.
Functions
Renders a navigation drawer. See the module doc.
Attributes
id(:string) (required) - builds the mobile toggle checkbox's id as "#{id}-toggle".color(:string) - surface (default) is the original plain look; the others also restyle nested List/ListItem content for contrast. Defaults to"surface". Must be one of"primary","secondary","tertiary", or"surface".elevation(:integer) - resting elevation (0-24), see PhoenixPaper.Elevation -- 0 pairs well with a caller-added border instead. Defaults to2.paperize(:boolean) - Defaults totrue.class(:any) - Defaults tonil.- Global attributes are accepted.
Slots
headerinner_block(required)
A hamburger button that toggles the pp_drawer/1 with the given for id.
Attributes
for(:string) (required) - the target pp_drawer/1's id.paperize(:boolean) - Defaults totrue.class(:any) - Defaults tonil.