An edge-attached panel - a "sheet" - for forms and detail views that don't warrant a
full page. origin decides which edge it slides from.
<.slide_over id="profile" origin="right" title="Edit profile">
Body
<:footer>
<button>Save</button>
</:footer>
</.slide_over>Bottom-sheet drawer mode
origin="bottom" is a first-class mobile drawer rather than a plain full-width panel:
rounded top corners, a border, env(safe-area-inset-bottom) padding, and a grab-handle
pill. The handle appears automatically - handle defaults to nil, which resolves to
true for origin="bottom" and false everywhere else. Pass it explicitly to override
in either direction.
<.slide_over id="filters" origin="bottom" title="Filters">
Body
</.slide_over>Drag-to-dismiss is on by default for bottom sheets. Drag the sheet down past roughly a
quarter of its height, or flick it down, and it closes through the exact same path as
Escape, the close button and click-away - the server still receives one
"close_slide_over" event.
<.slide_over id="queue" origin="bottom" snap_points={[0.4, 0.9]} initial_snap={0.4}>
Body
</.slide_over>snap_points are viewport-height fractions the drawer can rest at. It opens at
initial_snap (the first point when unset), drags between the points, and only a
downward release below the lowest point dismisses.
Dragging is a pointer-only enhancement layered over the dialog. Keyboard and
screen-reader users get exactly the behaviour they had before: role="dialog",
aria-modal, focus moved into the panel on open, Escape to close. The handle is
aria-hidden because it is decorative - the drag is the interaction, not the element.
Snap changes are visual only and are not announced. Under prefers-reduced-motion the
drawer settles instantly instead of springing.
The scale_background trade-off
scale_background shrinks and rounds the page behind an open drawer. It is off by
default because it puts a transform on the page wrapper, and a transformed ancestor
becomes the containing block for every position: fixed descendant - sticky headers and
fixed toolbars inside the page will move with it. It also forces a full-page repaint on
open and close. Turn it on only when the page behind the drawer is simple, and mark the
wrapper it should scale:
<div data-pc-drawer-wrapper>
<%!-- page content --%>
</div>
<.slide_over id="share" origin="bottom" scale_background title="Share">
Body
</.slide_over>Left, right and top sheets are unchanged by all of the above: no handle, no drag, no hook.
Summary
Functions
Attributes
id(:string) - Defaults to"slide-over".origin(:string) - slideover point of origin. Defaults to"right". Must be one of"left","right","top", or"bottom".close_slide_over_target(:string) - close_slide_over_target allows you to target a specific live component for the close event to go to. eg: close_slide_over_target={@myself}. Defaults tonil.close_on_click_away(:boolean) - whether the slideover should close when a user clicks away. Defaults totrue.close_on_escape(:boolean) - whether the slideover should close when a user hits escape. Defaults totrue.title(:string) - slideover title. Defaults tonil.description(:string) - a muted line under the title, for context the panel needs. Defaults tonil.max_width(:string) - sets container max-width. Defaults to"md". Must be one of"sm","md","lg","xl","2xl", or"full".on_open(Phoenix.LiveView.JS) - additional JS commands to run when the slide over opens. Defaults to%Phoenix.LiveView.JS{ops: []}.on_close(Phoenix.LiveView.JS) - additional JS commands to run when the slide over closes. Defaults to%Phoenix.LiveView.JS{ops: []}.handle(:boolean) - show the grab-handle pill. Defaults to true when origin="bottom", false otherwise. Set explicitly to override. Defaults tonil.drag_to_dismiss(:boolean) - for origin="bottom": drag the sheet down past a threshold (or flick with enough velocity) to dismiss. Pointer-only; Escape and the close button always work regardless. Ignored for other origins. Defaults totrue.snap_points(:list) - optional list of viewport-height fractions the drawer can rest at, e.g. [0.4, 0.9]. Drag between them; a fast flick skips to the next point in the flick direction. nil means content-height with a single rest position. Defaults tonil.initial_snap(:float) - which snap point the drawer opens at. Must be a member of snap_points. Defaults to the first entry. Defaults tonil.scale_background(:boolean) - scales and rounds the page behind the drawer while it is open. Off by default because it transforms the whole page (see the moduledoc for the trade-offs). Requires the consumer to mark the page wrapper with data-pc-drawer-wrapper. Defaults tofalse.class(:any) - CSS class. Defaults tonil.hide(:boolean) - slideover is hidden. Defaults tofalse.- Global attributes are accepted.
Slots
inner_blockfooter- a pinned action row at the bottom of the panel (save/cancel buttons).