Corex.FloatingPanel
(Corex v0.1.0-beta.4)
View Source
Phoenix implementation of Zag.js Floating Panel.
Examples
Basic
<.floating_panel id="my-floating-panel" class="floating-panel">
<:trigger class="button button--ghost button--sm">
<span data-closed>Open panel</span>
<span data-open>Close panel</span>
</:trigger>
<:title>Panel</:title>
<:minimize_trigger>
<.heroicon name="hero-arrow-down-left" class="icon" />
</:minimize_trigger>
<:maximize_trigger>
<.heroicon name="hero-arrows-pointing-out" class="icon" />
</:maximize_trigger>
<:default_trigger>
<.heroicon name="hero-rectangle-stack" class="icon" />
</:default_trigger>
<:close_trigger>
<.heroicon name="hero-x-mark" class="icon" />
</:close_trigger>
<:content>
<p>
Congue molestie ipsum gravida a. Sed ac eros luctus, cursus turpis
non, pellentesque elit. Pellentesque sagittis fermentum.
</p>
</:content>
</.floating_panel>Required slots: :trigger, :title, :close_trigger, :content.
Set class on :trigger to style the outer trigger button (e.g. button button--ghost button--sm).
Use data-open and data-closed on elements inside :trigger to swap label when the panel is open vs closed (see default rules in floating-panel.css). You can also target [data-part="trigger"][data-state="open"] / closed with your own selectors.
Optional slots: :minimize_trigger, :maximize_trigger, :default_trigger. Omit them to hide the minimize, maximize, and restore controls.
Set position={%Corex.Point{}} or position={%{x: n, y: n}} for a fixed initial Zag Point (data-default-position / defaultPosition). If position is set, it overrides anchor placement.
Set size={%{width:, height:}} for initial dimensions (data-default-size / Zag defaultSize). Use value_size for a controlled current size (data-size / Zag size).
Optional positioning={%Corex.Positioning{}} sets data-position-* for the client hook. When position is omitted, the hook passes Zag getAnchorPosition from placement and boundary (e.g. placement: "bottom-start" and gutter: 16 for a bottom corner). Do not rely on both position and positioning for the same panel; prefer position for explicit pixels, positioning for placement rules.
Styling
Use data attributes to target elements:
[data-scope="floating-panel"][data-part="root"] {}
[data-scope="floating-panel"][data-part="trigger"] {}
[data-scope="floating-panel"][data-part="positioner"] {}
[data-scope="floating-panel"][data-part="content"] {}
[data-scope="floating-panel"][data-part="title"] {}
[data-scope="floating-panel"][data-part="header"] {}
[data-scope="floating-panel"][data-part="body"] {}
[data-scope="floating-panel"][data-part="drag-trigger"] {}
[data-scope="floating-panel"][data-part="resize-trigger"] {}
[data-scope="floating-panel"][data-part="close-trigger"] {}
[data-scope="floating-panel"][data-part="control"] {}
[data-scope="floating-panel"][data-part="stage-trigger"] {}If you wish to use the default Corex styling, you can use the class floating-panel on the component.
This requires to install Mix.Tasks.Corex.Design first and import the component css file.
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/floating-panel.css";You can then use modifiers
<.floating_panel class="floating-panel floating-panel--accent floating-panel--lg">
<:trigger>
<span data-closed>Closed</span>
<span data-open>Open</span>
</:trigger>
<:title>Title</:title>
<:close_trigger>Close</:close_trigger>
<:content>Body</:content>
</.floating_panel>
Summary
API
Sets the panel open state from the browser. Returns a Phoenix.LiveView.JS command.
Sets the panel open state from the server. Pushes a LiveView hook event.
Components
Attributes
id(:string) - The id of the floating panel.draggable(:boolean) - Whether the panel can be dragged. Defaults totrue.resizable(:boolean) - Whether the panel can be resized. Defaults totrue.allow_overflow(:boolean) - Whether content can overflow. Defaults totrue.close_on_escape(:boolean) - Whether Escape closes the panel. Defaults totrue.disabled(:boolean) - Whether the panel is disabled. Defaults tofalse.dir(:string) - Text direction. Defaults tonil. Must be one ofnil,"ltr", or"rtl".orientation(:string) - Layout orientation for CSS and ignored attribute lists. Defaults to"vertical". Must be one of"horizontal", or"vertical".size(:map) - Zag defaultSize; sets data-default-size on the hook root. Defaults tonil.value_size(:map) - Zag controlled size; sets data-size when present. Defaults tonil.position(:any) - Initial ZagPoint(defaultPosition/data-default-position).%Corex.Point{}or%{x:, y:}. Defaults tonil.positioning(Corex.Positioning) - Optional placement forgetAnchorPositionon the client (data-position-*). Ignored for anchor math whenpositionis set. Defaults tonil.min_size(:map) - Minimum size constraints. Defaults tonil.max_size(:map) - Maximum size constraints. Defaults tonil.persist_rect(:boolean) - Whether to persist position and size. Defaults tofalse.grid_size(:integer) - Grid snapping size for drag and resize. Defaults to1.on_open_change(:string) - Server event when open state changes. Defaults tonil.on_open_change_client(:string) - Client event when open state changes. Defaults tonil.on_position_change(:string) - Server event when position changes. Defaults tonil.on_size_change(:string) - Server event when size changes. Defaults tonil.on_stage_change(:string) - Server event when stage (minimized/maximized) changes. Defaults tonil.translation(Corex.FloatingPanel.Translation) - Override translatable strings. Defaults tonil.- Global attributes are accepted.
Slots
trigger(required) - Accepts attributes:class(:string)
title(required) - Accepts attributes:class(:string)
minimize_trigger- Accepts attributes:class(:string)
maximize_trigger- Accepts attributes:class(:string)
default_trigger- Accepts attributes:class(:string)
close_trigger(required) - Accepts attributes:class(:string)
content(required) - Accepts attributes:class(:string)
API
Sets the panel open state from the browser. Returns a Phoenix.LiveView.JS command.
Examples
<.action phx-click={Corex.FloatingPanel.set_open("my-floating-panel", true)}>Open</.action>
Sets the panel open state from the server. Pushes a LiveView hook event.
Examples
def handle_event("open_panel", _, socket) do
{:noreply, Corex.FloatingPanel.set_open(socket, "my-floating-panel", true)}
end