Toolbar
v0.0.10
mix mishka.ui.gen.headless toolbar
Overview of the Phoenix and LiveView Headless Toolbar Component
The Mishka Chelekom Headless Toolbar is a bar of controls for Phoenix LiveView with no styling of its own. It renders the semantic markup with the WAI-ARIA wiring and roving-focus keyboard navigation over buttons, links, inputs, groups and separators. Arrow keys move focus along the orientation, looping when loop is set, while a focused input keeps its own cursor movement and hands navigation back only at the text boundaries.
Every control is an :item slot. Besides class for the toolbar itself, the root has a class attribute for each kind of part: button_class, link_class, input_class, separator_class and group_class. An item can add its own class on top.
Base UI Toolbar example (Phoenix headless)
Tab into the toolbar, then use the arrow keys, Home and End to move between the buttons and the link. Only one control is in the tab sequence at a time.
Base UI Toolbar example (Phoenix headless)
<.toolbar
id="baseui-toolbar-hero"
class="flex w-150 items-center gap-px border border-neutral-950 bg-white p-px dark:border-white dark:bg-neutral-950"
group_class="flex"
button_class="flex h-8 items-center gap-2 border-0 bg-transparent font-[inherit] text-sm leading-none whitespace-nowrap font-normal text-neutral-950 select-none hover:not-data-[disabled]:bg-neutral-100 active:not-data-[disabled]:bg-neutral-200 dark:text-white dark:hover:not-data-[disabled]:bg-neutral-800 dark:active:not-data-[disabled]:bg-neutral-700 focus-visible:bg-transparent focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-neutral-950 dark:focus-visible:outline-white"
separator_class="m-1 h-4 w-px bg-neutral-950 dark:bg-white"
link_class="font-[inherit] text-sm text-neutral-500 no-underline hover:text-blue-700 dark:text-neutral-400 dark:hover:text-blue-500 focus-visible:outline-2 focus-visible:outline-neutral-950 dark:focus-visible:outline-white"
>
<:item
group="Alignment"
label="Align left"
class="min-w-8 justify-center px-3"
>
Align Left
</:item>
<:item
group="Alignment"
label="Align right"
class="min-w-8 justify-center px-3"
>
Align Right
</:item>
<:item type="separator" />
<:item
group="Numerical format"
label="Format as currency"
class="min-w-8 justify-center"
>
$
</:item>
<:item
group="Numerical format"
label="Format as percent"
class="min-w-8 justify-center"
>
%
</:item>
<:item type="separator" />
<:item
label="Font family"
class="min-w-32 justify-between px-2"
>
Helvetica <.icon name="hero-chevron-up-down" class="block size-4" />
</:item>
<:item type="separator" />
<:item
type="link"
href="/chelekom/docs/headless/toolbar"
class="mr-[0.875rem] ml-auto flex-none self-center"
>
Edited 51m ago
</:item>
</.toolbar>Attributes and slots
id is required. orientation is "horizontal" (the default) or "vertical" and picks the arrow keys. loop is on by default and wraps focus past the ends. disabled disables the whole toolbar. focusable_when_disabled is on by default and keeps disabled items in the roving order, focusable but inert.
An :item takes type: "button" (the default), "link", "input" or "separator". It also takes disabled, label (the aria-label), href for a link, placeholder and value for an input, group, group_class and class. Consecutive items with the same group are wrapped in a role="group" element labelled with that name.
The root's button_class, link_class, input_class and separator_class go on every control of that type, and its group_class on every group. An item's class goes on that control only, after the root's classes. group_class on the first item of a group adds classes to that group only.
Parts & data attributes
Each part carries a stable data-part (where applicable) and a structural chelekom-toolbar__* class you can target, plus orientation and disabled state reflected as data attributes.
| Part | Element / role | State / ARIA | Purpose |
|---|---|---|---|
| Root | div, role="toolbar" | aria-orientation, aria-disabled, data-orientation, data-disabled | Carries the Toolbar hook; reads orientation/loop/disabled/focusable from data attributes; takes class. |
| Button | button | aria-disabled, data-orientation, data-disabled, data-focusable | Default item type; a roving-focus toolbar control; takes button_class. |
| Link | a | data-orientation | Item type "link"; participates in the same roving order; takes link_class. |
| Input | input | aria-disabled, data-orientation, data-disabled, data-focusable | Item type "input"; keeps its own cursor movement, hands navigation back at the text boundaries; takes input_class. |
| Group | div, role="group" | aria-label, data-orientation, data-disabled | Wraps consecutive items that share the same group label; takes group_class. |
| Separator | div, role="separator" | aria-orientation, data-orientation | Item type "separator"; a visual divider, not focusable; takes separator_class. |
Accessibility
Follows the WAI-ARIA Toolbar pattern: arrow keys move focus along the orientation and loop past the ends when loop is set, Home / End jump to the first / last item, and Tab moves focus out of the toolbar entirely. With focusable_when_disabled (the default), disabled items stay in the roving order, focusable but inert, so they remain discoverable. A control with no visible text needs a label.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
id
|
string
| — | — | Yes | — |
orientation
|
string
|
horizontal
|
horizontalvertical
| No | — |
loop
|
boolean
|
true
| — | No | Loop arrow-key focus past the ends |
disabled
|
boolean
|
false
| — | No | Disable the whole toolbar (data-disabled) |
focusable_when_disabled
|
boolean
|
true
| — | No | Keep disabled items in the roving order |
class
|
any
| — | — | No | — |
group_class
|
any
| — | — | No | — |
button_class
|
any
| — | — | No | — |
link_class
|
any
| — | — | No | — |
input_class
|
any
| — | — | No | — |
separator_class
|
any
| — | — | No | — |
rest
|
global
| — | — | No | — |
Slots
| Name | Required | Description |
|---|---|---|
item
| Yes | A toolbar control |
Attributes of the item slot
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
type
|
string
| — | — | No | button (default) | link | input | separator |
disabled
|
boolean
| — | — | No | — |
href
|
string
| — | — | No | For type=link |
label
|
string
| — | — | No | Accessible label (aria-label) |
placeholder
|
string
| — | — | No | For type=input |
value
|
string
| — | — | No | For type=input |
group
|
string
| — | — | No | Group label — consecutive same-group items are wrapped |
group_class
|
any
| — | — | No | Extra classes for the group wrapper (data-part=group) |
class
|
any
| — | — | No | — |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
toolbar
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.headless toolbar