PetalComponents.SlideOver (petal_components v4.16.1)

Copy Markdown View Source

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

hide_slide_over(origin, id \\ "slide-over", close_slide_over_target \\ nil)

show_slide_over(origin)

show_slide_over(origin, id)

show_slide_over(js, origin, id)

slide_over(assigns)

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 to nil.
  • close_on_click_away (:boolean) - whether the slideover should close when a user clicks away. Defaults to true.
  • close_on_escape (:boolean) - whether the slideover should close when a user hits escape. Defaults to true.
  • title (:string) - slideover title. Defaults to nil.
  • description (:string) - a muted line under the title, for context the panel needs. Defaults to nil.
  • 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 to nil.
  • 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 to true.
  • 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 to nil.
  • initial_snap (:float) - which snap point the drawer opens at. Must be a member of snap_points. Defaults to the first entry. Defaults to nil.
  • 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 to false.
  • class (:any) - CSS class. Defaults to nil.
  • hide (:boolean) - slideover is hidden. Defaults to false.
  • Global attributes are accepted.

Slots

  • inner_block
  • footer - a pinned action row at the bottom of the panel (save/cancel buttons).