The Voile dashboard component library.
These components implement the design system documented in
plans/dashboard-redesign.md. They are imported automatically by the
live_view_dashboard / controller_dashboard macros in VoileWeb, so every
/manage/* LiveView and the metaresource controllers can use them directly.
Summary
Functions
Returns the soft background CSS class for a semantic tone atom.
Returns the CSS color class for a semantic tone atom.
Renders a composite quick-action link: icon chip + label + description + trailing arrow. Used in the "Quick actions" card on the dashboard home.
Renders a uniform activity feed from a list of items.
Renders the mobile bottom navigation (visible only below lg). Five slots: Home, Catalog, primary-GLAM, Members, More.
A styled primary button matching the redesign.
Renders the command palette overlay (modal).
Destructive confirmation modal. Replaces delete_modal/1 and the ad-hoc
delete modals. DRAFT — not yet adopted.
Renders an empty-state block.
Brand-styled flash group. Drop-in for the core <.flash_group> used at the
top of the redesign layout. DRAFT — delegates to core; brand restyle pending.
Renders the footer shown at the bottom of the scrolling content area. Sticks to the viewport bottom when content is short (via flex-1 on the content wrapper); scrolls naturally when content is tall.
Renders the GLAM strip: four large tiles for the four GLAM types.
Renders a single GLAM type tile (the public version used by voile_glam_strip).
Drop-in replacement for the legacy glam_type_card/1. DRAFT API — stable.
Brand restyle wrapper around the core <.input>. Forwards the common attrs
and adds the voile-input class so the redesign focus ring (2px voile-primary,
2px offset) applies once the CSS lands. DRAFT — focus-ring CSS pending.
Brand-styled locale switcher. Drop-in for the core <.locale_switcher>.
DRAFT — delegates to core; brand restyle pending.
The master-data sub-navigation menu shared by every /manage/master/* page.
Pass to <.voile_settings_shell items={voile_master_nav_items()} ...>.
The metaresource sub-navigation menu shared by /manage/metaresource/* pages.
Renders a metric row: label on the left, value on the right, and an
optional proportional bar when a :total is supplied.
Brand-styled modal shell. Replaces collection_modal/1. Wraps the core
<.modal> with an optional eyebrow + title + body + optional footer.
DRAFT — not yet adopted.
Renders the canonical page header: eyebrow + title + description + actions. One per page.
Brand-styled pagination. Drop-in replacement for the legacy pagination/1.
Brand-styled search-insights widget. Replaces search_stats_widget/1.
stats shape: %{total_searches: n, popular_queries: [{q, count}], recent_activity: [...]}.
DRAFT — not yet adopted.
Renders a titled card that wraps content. The primary composition primitive.
The sub-navigation list used inside voile_settings_shell, or standalone where a
page keeps its own layout but still wants the settings/master/plugin nav
(e.g. a deep edit page that replaced <.dashboard_settings_sidebar>).
The standard settings sub-navigation menu shared by every /manage/settings/*
page. Pass to <.voile_settings_shell items={voile_settings_nav_items()} ...>.
Two-pane "sub-nav + content" shell for settings, plugins, master-data and
metaresource pages. Replaces dashboard_settings_sidebar/1,
plugin_settings_sidebar/1, and the inline master/metaresource sidebars.
Renders the persistent desktop sidebar (lg+).
Renders a brand-aware stat card with optional trend and sparkline.
Brand-styled data table. Replaces the core <.table> with redesign tokens:
brand-tinted header, row hover, optional empty slot, and an actions column.
Renders the sticky topbar with breadcrumb, command palette trigger, notifications, theme toggle, and user avatar.
Functions
Returns the soft background CSS class for a semantic tone atom.
Returns the CSS color class for a semantic tone atom.
Renders a composite quick-action link: icon chip + label + description + trailing arrow. Used in the "Quick actions" card on the dashboard home.
Attributes
icon(:string) (required)tone(:atom) (required)label(:string) (required)description(:string) (required)href(:string) (required)
Renders a uniform activity feed from a list of items.
Each item is a map with keys:
:icon— hero-* icon name:tone— semantic tone atom:title— bold first line:subtitle— secondary text (optional):meta— right-aligned meta text (e.g. timestamp) (optional):href— link target (optional)
Attributes
items(:list) (required)empty_text(:string) - Defaults tonil.
A styled primary button matching the redesign.
Attributes
href(:string) - Defaults tonil.type(:string) - Defaults to"button".tone(:atom) - Defaults to:brand.variant(:atom) - Defaults to:solid.size(:atom) - Defaults to:md.class(:string) - Defaults tonil.- Global attributes are accepted. Supports all globals plus:
["disabled", "form", "name", "value"].
Slots
inner_block(required)
Renders the command palette overlay (modal).
Listens for ⌘K via the CommandPalette hook. Items are static for the demo;
in production these will be live-driven via a pushEvent to query collections.
Attributes
current_path(:string) - Defaults to"/manage".
Destructive confirmation modal. Replaces delete_modal/1 and the ad-hoc
delete modals. DRAFT — not yet adopted.
Attributes
id(:string) (required)show(:boolean) - Defaults tofalse.title(:string) - Defaults tonil.confirm_label(:string) - Defaults to"Hapus".on_cancel(Phoenix.LiveView.JS) - Defaults to%Phoenix.LiveView.JS{ops: []}.on_confirm(Phoenix.LiveView.JS) - Defaults to%Phoenix.LiveView.JS{ops: []}.
Slots
inner_block(required)
Renders an empty-state block.
Attributes
icon(:string) (required)title(:string) (required)description(:string) - Defaults tonil.tone(:atom) - Defaults to:brand.
Slots
actions
Brand-styled flash group. Drop-in for the core <.flash_group> used at the
top of the redesign layout. DRAFT — delegates to core; brand restyle pending.
Attributes
flash(:map) (required)id(:string) - Defaults to"voile-flash-group".
Renders the GLAM strip: four large tiles for the four GLAM types.
Attributes
stats(:map) (required)
Renders a single GLAM type tile (the public version used by voile_glam_strip).
Drop-in replacement for the legacy glam_type_card/1. DRAFT API — stable.
Attributes
type(:atom) (required)count(:integer) (required)delta(:integer) - Defaults to0.href(:string) (required)
Brand restyle wrapper around the core <.input>. Forwards the common attrs
and adds the voile-input class so the redesign focus ring (2px voile-primary,
2px offset) applies once the CSS lands. DRAFT — focus-ring CSS pending.
Attributes
field(Phoenix.HTML.FormField) - Defaults tonil.name(:any)value(:any)type(:string) - Defaults to"text".label(:string) - Defaults tonil.class(:string) - Defaults tonil.- Global attributes are accepted.
Brand-styled locale switcher. Drop-in for the core <.locale_switcher>.
DRAFT — delegates to core; brand restyle pending.
Attributes
current_path(:string) - Defaults to"/".class(:string) - Defaults tonil.
Renders a metric row: label on the left, value on the right, and an
optional proportional bar when a :total is supplied.
Attributes
label(:string) (required)value(:any) (required)total(:any) - Defaults tonil.tone(:atom) - Defaults to:brand.
Brand-styled modal shell. Replaces collection_modal/1. Wraps the core
<.modal> with an optional eyebrow + title + body + optional footer.
DRAFT — not yet adopted.
Attributes
id(:string) (required)show(:boolean) - Defaults tofalse.on_cancel(Phoenix.LiveView.JS) - Defaults to%Phoenix.LiveView.JS{ops: []}.eyebrow(:string) - Defaults tonil.title(:string) - Defaults tonil.
Slots
inner_block(required)footer
Renders the canonical page header: eyebrow + title + description + actions. One per page.
Attributes
eyebrow(:string) - Defaults tonil.title(:string) (required)description(:string) - Defaults tonil.icon(:string) - Defaults tonil.tone(:atom) - Defaults to:brand.
Slots
actions
Brand-styled pagination. Drop-in replacement for the legacy pagination/1.
Modes
- link — pass
:path; renders<.link patch>(URL built from:params). - button — omit
:path; renders<.button phx-click={event} phx-value-page>.
DRAFT — not yet adopted.
Attributes
page(:integer) (required)total_pages(:integer) (required)path(:string) - Defaults tonil.event(:string) - Defaults to"paginate".params(:map) - Defaults to%{}.
Brand-styled search-insights widget. Replaces search_stats_widget/1.
stats shape: %{total_searches: n, popular_queries: [{q, count}], recent_activity: [...]}.
DRAFT — not yet adopted.
Attributes
stats(:map) - Defaults to%{}.action_path(:string) - Defaults tonil.
Renders a titled card that wraps content. The primary composition primitive.
Attributes
title(:string) - Defaults tonil.icon(:string) - Defaults tonil.tone(:atom) - Defaults to:brand.action_label(:string) - Defaults tonil.action_path(:string) - Defaults tonil.class(:string) - Defaults tonil.
Slots
inner_block(required)
Two-pane "sub-nav + content" shell for settings, plugins, master-data and
metaresource pages. Replaces dashboard_settings_sidebar/1,
plugin_settings_sidebar/1, and the inline master/metaresource sidebars.
items is a list of maps: %{label: "...", path: "/...", icon: "hero-..."}
(icon optional). On desktop it renders a sticky left card; on mobile it
collapses to a horizontal chip strip so it doesn't push the form below the fold.
Use voile_settings_nav_items/0 for the standard settings menu.
Attributes
title(:string) - Defaults tonil.items(:list) (required)current_path(:string) - Defaults tonil.
Slots
inner_block(required)
Renders the persistent desktop sidebar (lg+).
Inside the redesign layout, this is always paired with
<.voile_bottom_nav> for mobile.
Attributes
current_path(:string) - Defaults to"/manage".user(:map) - Defaults tonil.
Renders a brand-aware stat card with optional trend and sparkline.
Examples
<.voile_stat_card
label="Total Members"
value="1,204"
icon="hero-users"
tone={:success}
trend=%{direction: :up, value: "+12%", period: "vs last week"}
/>Attributes
label(:string) (required)value(:any) (required)unit(:string) - Defaults tonil.icon(:string) - Defaults tonil.tone(:atom) - Defaults to:brand.trend(:map) - Defaults tonil.sparkline(:list) - Defaults tonil.href(:string) - Defaults tonil.loading(:boolean) - Defaults tofalse.class(:string) - Defaults tonil.
Brand-styled data table. Replaces the core <.table> with redesign tokens:
brand-tinted header, row hover, optional empty slot, and an actions column.
Columns use :let={row}:
<:col :let={row} label="Title">{row.title}</:col>DRAFT — not yet adopted. (LiveStream support is pending; currently iterates a list.)
Attributes
id(:string) (required)rows(:any) (required)row_id(:any) - Defaults tonil.
Slots
col(required) - Accepts attributes:label(:string)
actionempty
Renders the sticky topbar with breadcrumb, command palette trigger, notifications, theme toggle, and user avatar.
Attributes
current_path(:string) - Defaults to"/manage".user(:map) - Defaults tonil.breadcrumb(:list) - Defaults to[].notification_count(:integer) - Defaults to0.