Corex.Collapsible
(Corex v0.1.0-beta.3)
View Source
Phoenix implementation of Zag.js Collapsible.
Examples
Basic
<.collapsible id="my-collapsible">
<:trigger>Toggle Content</:trigger>
<:content>
This content can be collapsed and expanded.
</:content>
</.collapsible>With opened and closed surfaces
Optional :closed and :opened slots render after the trigger label (same button). Use one chevron in :closed and default CSS rotates it when open (like Accordion). Use both slots to swap different markup when open vs closed.
<.collapsible id="my-collapsible">
<:trigger>Toggle Content</:trigger>
<:closed>
<.heroicon name="hero-chevron-down" />
</:closed>
<:content>
This content can be collapsed and expanded.
</:content>
</.collapsible>Custom with :let
Use :let={collapsible} on :trigger, :content, :closed, or :opened to access collapsible.open and collapsible.disabled.
<.collapsible id="my-collapsible">
<:trigger :let={collapsible}>
{if collapsible.open, do: "Collapse", else: "Expand"}
</:trigger>
<:content :let={_c}>Panel body</:content>
<:closed :let={collapsible}>
<.heroicon name={if collapsible.open, do: "hero-minus", else: "hero-plus"} />
</:closed>
</.collapsible>Controlled
<.collapsible
id="my-collapsible"
controlled
open={@collapsible_open}
on_open_change="collapsible_changed">
<:trigger>Toggle Content</:trigger>
<:content>
This content can be collapsed and expanded.
</:content>
</.collapsible>def handle_event("collapsible_changed", %{"open" => open}, socket) do
{:noreply, assign(socket, :collapsible_open, open)}
endAPI Control
In order to use the API, you must use an id on the component
Client-side
<button phx-click={Corex.Collapsible.set_open("my-collapsible", true)}>
Open
</button>Server-side
def handle_event("open_collapsible", _, socket) do
{:noreply, Corex.Collapsible.set_open(socket, "my-collapsible", true)}
endStyling
Target parts with data-scope="collapsible" and data-part:
[data-scope="collapsible"][data-part="root"] {}
[data-scope="collapsible"][data-part="trigger"] {}
[data-scope="collapsible"][data-part="content"] {}
[data-scope="collapsible"][data-part="closed"] {}
[data-scope="collapsible"][data-part="opened"] {}Root, trigger, and content have data-state="open" or data-state="closed". When the trigger is focused, data-focus is set on root, trigger, and content.
The content part exposes --height, --width, --collapsed-height, and --collapsed-width for animations. Example:
[data-scope="collapsible"][data-part="content"] {
overflow: hidden;
}
[data-scope="collapsible"][data-part="content"][data-state="open"] {
animation: expand 110ms cubic-bezier(0, 0, 0.38, 0.9);
}
[data-scope="collapsible"][data-part="content"][data-state="closed"] {
animation: collapse 110ms cubic-bezier(0, 0, 0.38, 0.9);
}
@keyframes expand {
from { height: var(--collapsed-height, 0); }
to { height: var(--height); }
}
@keyframes collapse {
from { height: var(--height); }
to { height: var(--collapsed-height, 0); }
}If you wish to use the default Corex styling, you can use the class collapsible on the component.
This requires you 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/collapsible.css";You can then use modifiers
<.collapsible class="collapsible collapsible--accent collapsible--lg">
Summary
Components
Renders a collapsible component.
API
Sets the collapsible open state from client-side. Returns a Phoenix.LiveView.JS command.
Sets the collapsible open state from server-side. Pushes a LiveView event.
Components
Renders a collapsible component.
Requires :trigger and :content slots. Optional :closed and :opened slots add visual surfaces after the trigger label (Connect data-part only, no Zag props). Use :let={collapsible} on slots to access collapsible.open and collapsible.disabled.
Attributes
id(:string) - The id of the collapsible, useful for API to identify the collapsible.open(:boolean) - The initial open state or the controlled open state. Defaults tofalse.controlled(:boolean) - Whether the collapsible is controlled. Only in LiveView, the on_open_change event is required. Defaults tofalse.disabled(:boolean) - Whether the collapsible is disabled. Defaults tofalse.dir(:string) - The direction of the collapsible. When nil, derived from document (html lang + config :rtl_locales). Defaults tonil. Must be one ofnil,"ltr", or"rtl".orientation(:string) - Layout orientation for CSS. Defaults to"vertical". Must be one of"horizontal", or"vertical".on_open_change(:string) - The server event name when the open state changes. Defaults tonil.on_open_change_client(:string) - The client event name when the open state changes. Defaults tonil.- Global attributes are accepted.
Slots
trigger(required) - Trigger button content. Use :let={collapsible} to access open and disabled state. Accepts attributes:class(:string)
content(required) - Expandable content. Use :let={collapsible} to access open and disabled state. Accepts attributes:class(:string)
closed- Optional surface after the trigger, visible when closed (or use with:openedto swap content by state). Accepts attributes:class(:string)
opened- Optional surface after the trigger, visible when open (use with:closedto swap content by state). Accepts attributes:class(:string)
API
Sets the collapsible open state from client-side. Returns a Phoenix.LiveView.JS command.
Examples
<button phx-click={Corex.Collapsible.set_open("my-collapsible", true)}>
Open
</button>
Sets the collapsible open state from server-side. Pushes a LiveView event.
Examples
def handle_event("open_collapsible", _params, socket) do
socket = Corex.Collapsible.set_open(socket, "my-collapsible", true)
{:noreply, socket}
end
Functions
Attributes
dir(:string) - Same as collapsible: logical direction for the skeleton root. Defaults tonil. Must be one ofnil,"ltr", or"rtl".orientation(:string) - Same as collapsible: layout orientation for CSS. Defaults to"vertical". Must be one of"horizontal", or"vertical".- Global attributes are accepted.