Corex.Accordion (Corex v0.1.0-alpha.13)
View SourcePhoenix implementation of Zag.js Accordion.
Examples
List
You must use Corex.Accordion.Item struct for items.
The value for each item is optional, useful for controlled mode and API to identify the item.
You can specify disabled for each item.
<.accordion
class="accordion"
items={[
%Corex.Accordion.Item{
trigger: "Lorem ipsum dolor sit amet",
content: "Consectetur adipiscing elit. Sed sodales ullamcorper tristique."
},
%Corex.Accordion.Item{
trigger: "Duis dictum gravida odio ac pharetra?",
content: "Nullam eget vestibulum ligula, at interdum tellus."
},
%Corex.Accordion.Item{
trigger: "Donec condimentum ex mi",
content: "Congue molestie ipsum gravida a. Sed ac eros luctus."
}
]}
/>List Custom
Similar to List but render a custom item slot that will be used for all items.
Use {item.meta.trigger} and {item.meta.content} to render the trigger and content for each item.
This example assumes the import of .icon from Core Components
<.accordion
class="accordion"
items={[
%Corex.Accordion.Item{
value: "lorem",
trigger: "Lorem ipsum dolor sit amet",
content: "Consectetur adipiscing elit. Sed sodales ullamcorper tristique.",
meta: %{
indicator: "hero-chevron-right",
}
},
%Corex.Accordion.Item{
trigger: "Duis dictum gravida odio ac pharetra?",
content: "Nullam eget vestibulum ligula, at interdum tellus.",
meta: %{
indicator: "hero-chevron-right",
}
},
%Corex.Accordion.Item{
value: "donec",
trigger: "Donec condimentum ex mi",
content: "Congue molestie ipsum gravida a. Sed ac eros luctus.",
disabled: true,
meta: %{
indicator: "hero-chevron-right",
}
}
]}
>
<:item :let={item}>
<.accordion_trigger item={item}>
{item.data.trigger}
<:indicator>
<.icon name={item.data.meta.indicator} />
</:indicator>
</.accordion_trigger>
<.accordion_content item={item}>
{item.data.content}
</.accordion_content>
</:item>
</.accordion>Custom
Render a custom item slot per accordion item manually.
Use let={item} to get the item data and pass it to the accordion_trigger/1 and accordion_content/1 components.
The trigger component takes an optional :indicator slot to render the indicator ico
This example assumes the import of .icon from Core Components
<.accordion id="my-accordion" value={["duis"]} class="accordion">
<:item :let={item} value="lorem" disabled>
<.accordion_trigger item={item}>
Lorem ipsum dolor sit amet
<:indicator>
<.icon name="hero-chevron-right" />
</:indicator>
</.accordion_trigger>
<.accordion_content item={item}>
Consectetur adipiscing elit. Sed sodales ullamcorper tristique. Proin quis risus feugiat tellus iaculis fringilla.
</.accordion_content>
</:item>
<:item :let={item} value="duis">
<.accordion_trigger item={item}>
Duis dictum gravida odio ac pharetra?
<:indicator>
<.icon name="hero-chevron-right" />
</:indicator>
</.accordion_trigger>
<.accordion_content item={item}>
Nullam eget vestibulum ligula, at interdum tellus. Quisque feugiat, dui ut fermentum sodales, lectus metus dignissim ex.
</.accordion_content>
</:item>
</.accordion>Controlled
Render an accordion controlled by the server.
You must use the on_value_change event to update the value on the server and pass the value as a list of strings.
The event will receive the value as a map with the key value and the id of the accordion.
defmodule MyAppWeb.AccordionLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
{:ok, assign(socket, :value, ["lorem"])}
end
def handle_event("on_value_change", %{"value" => value}, socket) do
{:noreply, assign(socket, :value, value)}
end
def render(assigns) do
~H"""
<.accordion value={@value} on_value_change="on_value_change" class="accordion">
<:item :let={item} value="lorem">
<.accordion_trigger item={item}>
Lorem ipsum dolor sit amet
</.accordion_trigger>
<.accordion_content item={item}>
Consectetur adipiscing elit. Sed sodales ullamcorper tristique. Proin quis risus feugiat tellus iaculis fringilla.
</.accordion_content>
</:item>
<:item :let={item} value="duis">
<.accordion_trigger item={item}>
Duis dictum gravida odio ac pharetra?
</.accordion_trigger>
<.accordion_content item={item}>
Nullam eget vestibulum ligula, at interdum tellus. Quisque feugiat, dui ut fermentum sodales, lectus metus dignissim ex.
</.accordion_content>
</:item>
</.accordion>
"""
end
end
Async
When the initial props are not available on mount, you can use the Phoenix.LiveView.assign_async function to assign the props asynchronously
You can use the optional Corex.Accordion.accordion_skeleton/1 to render a loading or error state
defmodule MyAppWeb.AccordionAsyncLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
socket =
socket
|> assign_async(:accordion, fn ->
Process.sleep(1000)
items = [
%Corex.Accordion.Item{
value: "lorem",
trigger: "Lorem ipsum dolor sit amet",
content: "Consectetur adipiscing elit. Sed sodales ullamcorper tristique.",
disabled: true
},
%Corex.Accordion.Item{
value: "duis",
trigger: "Duis dictum gravida odio ac pharetra?",
content: "Nullam eget vestibulum ligula, at interdum tellus."
},
%Corex.Accordion.Item{
value: "donec",
trigger: "Donec condimentum ex mi",
content: "Congue molestie ipsum gravida a. Sed ac eros luctus."
}
]
{:ok,
%{
accordion: %{
items: items,
value: ["duis", "donec"]
}
}}
end)
{:ok, socket}
end
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<div class="layout__row">
<h1>Accordion</h1>
<h2>Async</h2>
</div>
<.async_result :let={accordion} assign={@accordion}>
<:loading>
<.accordion_skeleton count={3} class="accordion" />
</:loading>
<:failed>
there was an error loading the accordion
</:failed>
<.accordion
id="async-accordion"
class="accordion"
items={accordion.items}
value={accordion.value}
/>
</.async_result>
</Layouts.app>
"""
end
end
API Control
Client-side
<button phx-click={Corex.Accordion.set_value("my-accordion", ["item-1"])}>
Open Item 1
</button>
Server-side
def handle_event("open_item", _, socket) do
{:noreply, Corex.Accordion.set_value(socket, "my-accordion", ["item-1"])}
endStyling
Use data attributes to target elements:
[data-scope="accordion"][data-part="root"] {}
[data-scope="accordion"][data-part="item"] {}
[data-scope="accordion"][data-part="item-trigger"] {}
[data-scope="accordion"][data-part="item-content"] {}
[data-scope="accordion"][data-part="item-indicator"] {}
Summary
Components
Renders an accordion component.
Renders the accordion content area.
Renders a loading skeleton for the accordion component.
Renders the accordion trigger button. Includes optional :indicator slot.
API
Sets the accordion value from client-side. Returns a Phoenix.LiveView.JS command.
Sets the accordion value from server-side. Pushes a LiveView event.
Components
Renders an accordion component.
You can use either:
- The
:itemslot for manual item definition with full control - The
:itemsattribute for programmatic item generation from a list of%Corex.Accordion.Item{}structs
When using :items, each item MUST be a %Corex.Accordion.Item{} struct with:
:value(required) - unique identifier for the item:trigger(required) - content for the trigger button:content(optional, default: "") - content for the accordion panel:disabled(optional, default: false) - whether the item is disabled
Attributes
id(:string) - The id of the accordion, useful for API to identify the accordion.items(:list) - The items of the accordion, must be a list of %Corex.Accordion.Item{} structs. Defaults tonil.value(:list) - The initial value or the controlled value of the accordion, must be a list of strings. Defaults to[].controlled(:boolean) - Whether the accordion is controlled. Only in LiveView, the on_value_change event is required. Defaults tofalse.collapsible(:boolean) - Whether the accordion is collapsible. Defaults totrue.disabled(:boolean) - Whether the accordion is disabled. Defaults tofalse.multiple(:boolean) - Whether the accordion allows multiple items to be selected. Defaults totrue.orientation(:string) - The orientation of the accordion. Defaults to"vertical". Must be one of"horizontal", or"vertical".dir(:string) - The direction of the accordion. Defaults to"ltr". Must be one of"ltr", or"rtl".on_value_change(:string) - The server event name when the value change. Defaults tonil.on_value_change_client(:string) - The client event name when the value change. Defaults tonil.on_focus_change(:string) - The server event name when the focus change. Defaults tonil.on_focus_change_client(:string) - The client event name when the focus change. Defaults tonil.- Global attributes are accepted.
Slots
item- Accepts attributes:value(:string) - The value of the item, useful in controlled mode and for API to identify the item.disabled(:boolean) - Whether the item is disabled.
Renders the accordion content area.
Attributes
item(:map) (required)
Slots
inner_block(required)
Renders a loading skeleton for the accordion component.
Attributes
count(:integer) - Defaults to3.- Global attributes are accepted.
Slots
triggerindicatorcontent
Renders the accordion trigger button. Includes optional :indicator slot.
Attributes
item(:map) (required)
Slots
inner_block(required)indicator
API
Sets the accordion value from client-side. Returns a Phoenix.LiveView.JS command.
Examples
<button phx-click={Corex.Accordion.set_value("my-accordion", ["item-1"])}>
Open Item 1
</button>
Sets the accordion value from server-side. Pushes a LiveView event.
Examples
def handle_event("open_item", _params, socket) do
socket = Corex.Accordion.set_value(socket, "my-accordion", ["item-1"])
{:noreply, socket}
end