LineOne's drawer: a full-height panel that slides in from the left or the right over a dark
backdrop. Bare, it is a sliding frame for a menu; with a title (or a :header) and a :footer
it is a sheet, the panel a form or a detail opens in: a header with the title, its description
and the close ×, a body that scrolls, and a footer with the buttons.
<.button phx-click={LineaUI.toggle("menu")}>Menu</.button>
<.drawer id="menu" side="right">
<nav class="p-5">…</nav>
</.drawer>
<.drawer id="customer" placement="right" size="md" title="New customer"
description="Who buys from you." on_close="cancel">
<.form for={@form} id="customer-form" phx-submit="save">…</.form>
<:footer>
<.button variant="outline" phx-click={LineaUI.close("customer")}>Cancel</.button>
<.button type="submit" form="customer-form" color="primary">Save</.button>
</:footer>
</.drawer>size sets the sheet's width (sm 400px, md 560px, lg 760px, xl 1080px), never wider
than the screen, so it is full width on a phone. Buttons in the header go in :actions, a back
arrow (a sheet opened from another) in :back.
Like the modal it opens from the browser (LineaUI.open/close/toggle("id")), from the server
(LineaUI.open(socket, "id")) or from open; on_close runs however it closed (Esc, the
backdrop, the ×, a command), so the server can follow. By default a drawer does not lock the
page's scroll, as in LineOne (lock_scroll locks it).
Drawers and modals stack in the order they open: a drawer opened from another (a detail, then
its edit form), or a modal opened from a drawer, is drawn above it; Esc and the backdrop close
only the one on top. The second overlay may sit next to the first or inside its markup (a
confirm rendered in the sheet's body or footer): the open drawer carries no CSS transform
(the slide is an animation that only runs while it enters and leaves, with no fill), so it
is not a containing block for position: fixed and a modal inside it still covers the whole
viewport, above the drawer. Keep panel_class and class free of transform, filter,
backdrop-filter, perspective and contain for the same reason. Nothing is moved out of
the LiveView's DOM, so patches reach the nested modal as usual.
The layers come from the CSS custom properties --linea-z-overlay (drawers) and
--linea-z-modal (modals), see the README.
Summary
Functions
Renders a drawer, closed unless open.
Functions
Renders a drawer, closed unless open.
Events: on_open and on_close push %{"id" => id} when they are event names.
Attributes
id(:string) (required)open(:boolean) - Defaults tofalse.side(:string) - Defaults to"left". Must be one of"left", or"right".placement(:string) - The same asside, which it overrides when given. Defaults tonil. Must be one ofnil,"left", or"right".size(:string) - The sheet's width:sm400px,md560px,lg760px,xl1080px, full width on a phone.nilis LineOne'sw-72frame. Defaults tonil. Must be one ofnil,"sm","md","lg", or"xl".title(:string) - The sheet's title; draws the header. Defaults tonil.description(:string) - A line under the title. Defaults tonil.close_button(:boolean) - The × at the end of the header (only drawn when there is a header). Defaults totrue.close_label(:string) - Defaults to"Close".overlay(:boolean) - The dark backdrop, which closes the drawer when clicked. Defaults totrue.lock_scroll(:boolean) - Locks the page's scroll while it is open, as a modal does. Defaults tofalse.prevent_close(:boolean) - Esc and the backdrop do not close it. Defaults tofalse.on_open(:any) - An event name or a%JS{}. Defaults tonil.on_close(:any) - An event name or a%JS{}. Defaults tonil.target(:any) - Thephx-targetofon_open/on_closeevents. Defaults tonil.class(:any) - Merged into the sliding frame: its width (size, orw-72; e.g.class="w-96") and shadow. Defaults tonil.panel_class(:any) - Merged into the white panel inside the frame. Defaults tonil.body_class(:any) - Merged into the scrolling body of a sheet (px-6 py-5, a column withgap-4). Defaults tonil.- Global attributes are accepted.
Slots
header- The header's content instead oftitleanddescription; the back arrow, the actions and the × still frame it. Accepts attributes:class(:any)
back- Before the title: the button back to the sheet this one was opened from (phx-click={LineaUI.close("this")}).actions- Buttons at the end of the header, before the ×.footer- The buttons under the body, aligned to the end, on a tinted bar. Accepts attributes:class(:any)
inner_block(required)