Overflow List
v0.0.10
mix mishka.ui.gen.headless overflow_list
Overview of the Phoenix and LiveView Headless Overflow List Component
The Mishka Chelekom Headless Overflow List lays items out on one row in Phoenix and LiveView and folds the ones that do not fit into a +N counter. It renders a div that carries the OverflowList JavaScript hook, one span for each item slot, and a counter. A ResizeObserver re-runs the layout whenever the container width changes. The generator copies overflow_list.js into assets/vendor and wires the hook in.
Items that do not fit get data-hidden and inert, which removes them from the tab order and the accessibility tree. The component does not hide them for you: add a rule such as [&_[data-part=item][data-hidden]]:hidden to the root classes. The counter starts with data-hidden and is revealed when something overflows, with the hidden count written into its counter-value part. Order is priority, so the last items fold first, and min_visible (1 by default) is how many always stay. id is required because the hook attaches to it. Class attributes: class, item_class, counter_class and counter_value_class.
Overflow List example - a box you can resize (Phoenix headless)
Overflow List example - a box you can resize (Phoenix headless)
<div class="w-[26rem] min-w-28 max-w-full resize-x overflow-auto rounded-lg border border-neutral-300 bg-white p-2 dark:border-neutral-700 dark:bg-neutral-900">
<.overflow_list
id="resizable-overflow-list"
min_visible={1}
class={@row_classes}
item_class="whitespace-nowrap rounded-full bg-neutral-100 px-2.5 py-0.5 text-sm text-neutral-700 dark:bg-neutral-800 dark:text-neutral-200"
>
<:item :for={tag <- @tags}>{tag}</:item>
</.overflow_list>
</div>Reacting on the server
on_change names a LiveView event. The hook pushes it with %{"hidden" => n} when the hidden count changes. The push is debounced, so dragging a resize handle does not flood the server.
<.overflow_list id="tags" on_change="overflow" class={@row_classes} item_class="...">
<:item :for={tag <- @tags}>{tag}</:item>
</.overflow_list>
<p>Hidden on the server: {@hidden}</p>def handle_event("overflow", %{"hidden" => hidden}, socket) do
{:noreply, assign(socket, hidden: hidden)}
endParts & data attributes
The root carries chelekom-overflow-list, data-min-visible and data-on-change. Each part has a data-part value and a chelekom-overflow-list__* class.
itemis one list item. It getsdata-hiddenandinertwhile it overflows.counteris the+Nelement. It hasdata-hiddenwhile nothing overflows.counter-valuereceives the hidden count as text.
Accessibility
There is no formal WAI-ARIA pattern for an overflow list. Overflowing items are made inert, so keyboard and screen reader users reach only what is visible. The counter is plain text, not a control. If people need the hidden items, show them elsewhere using the count from on_change.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
id
|
string
| — | — | Yes | Unique id (carries the OverflowList hook) |
min_visible
|
integer
|
1
| — | No | Minimum items to always keep visible |
on_change
|
string
| — | — | No | Event pushed with %{hidden: n} when the count changes |
class
|
any
| — | — | No | Extra classes for the root |
item_class
|
any
| — | — | No | Extra classes for each item |
counter_class
|
any
| — | — | No | Extra classes for the counter |
counter_value_class
|
any
| — | — | No | — |
rest
|
global
| — | — | No | — |
Slots
| Name | Required | Description |
|---|---|---|
item
| Yes | One entry per list item (order = priority) |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
overflow_list
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.headless overflow_list