Fluxon.Components.Button
(Fluxon v3.0.0)
Provides <.button> and <.button_group> components for interactive actions and navigation.
The button component renders either a <button> or an <a> element depending on the
attributes passed to it, so the same component covers form submissions, click handlers,
and navigation links. It exposes visual variants, semantic colors, and size options
(including dedicated icon-only sizes) that automatically scale any nested <.icon>.
The companion <.button_group> joins adjacent buttons into a single connected unit,
removing inner border radii and overlapping borders so the buttons read as one control.
Usage
Render a button with the default styling:
<.button>Default Button</.button>Combine variant and color to communicate priority and intent:
<.button variant="solid" color="primary">Save</.button>
<.button variant="soft" color="info">Learn more</.button>
<.button variant="ghost">Cancel</.button>Wire LiveView events directly through the rest attribute:
<.button variant="solid" color="primary" phx-click="save">
Save Changes
</.button>Visual Variants
Each variant tunes background, border, and shadow treatment for a specific level of emphasis. The available variants are:
<.button variant="solid" color="primary">Solid</.button>
<.button variant="soft" color="primary">Soft</.button>
<.button variant="surface" color="primary">Surface</.button>
<.button variant="outline">Outline (Default)</.button>
<.button variant="dashed">Dashed</.button>
<.button variant="ghost">Ghost</.button>solid: filled background with the strongest visual weight. Use for the single primary action on a screen (save, submit, continue).soft: tinted background without a visible border. Use for secondary actions that should feel related to the primary action.surface: same tinted background assoftplus a colored border. Use for contained secondary actions that need a clearer boundary.outline: bordered with a transparent background. Default. Use for neutral actions and most general-purpose buttons.dashed: dashed border with transparent background. Use for placeholder, draft, or "add" actions that hint at incompleteness.ghost: no border or background until hover. Use for toolbar buttons, icon-only affordances, and minimal utility actions.
Semantic Colors
Colors carry meaning across both light and dark modes. Each color defines styles for every variant. The available colors are:
<.button color="primary" variant="solid">Primary</.button>
<.button color="info" variant="soft">Info</.button>
<.button color="success" variant="surface">Success</.button>
<.button color="warning" variant="outline">Warning</.button>
<.button color="danger" variant="ghost">Danger</.button>primary: the most important action in the current context (save, submit, continue).info: informational actions (view details, learn more, open docs).success: positive actions and confirmations (approve, confirm, mark complete).warning: actions that need extra attention (proceed despite a warning, retry).danger: destructive or irreversible actions (delete, remove, revoke).
Sizes
Sizes scale height, padding, font size, and the size of any nested icon. Use them to match the surrounding density of the screen:
<.button size="xs">Extra Small</.button>
<.button size="sm">Small</.button>
<.button size="md">Medium (Default)</.button>
<.button size="lg">Large</.button>
<.button size="xl">Extra Large</.button>| Size | Height | Text | Icon Size | Use Case |
|---|---|---|---|---|
xs | 28px | xs | 14px | Compact UI, dense tables, inline controls |
sm | 32px | sm | 16px | Secondary actions, toolbar buttons |
md | 36px | sm | 16px | Default. Most form and page actions |
lg | 40px | sm | 18px | Primary actions on form-heavy pages |
xl | 44px | base | 20px | Hero sections, prominent calls to action |
Icon-Only Sizes
Square sizes are tuned for buttons whose only content is an icon. They keep the icon visually centered without extra padding tweaks:
<.button size="icon-sm" aria-label="Edit">
<.icon name="hero-pencil" class="icon" />
</.button>
<.button size="icon" variant="solid" color="primary" aria-label="Search">
<.icon name="hero-magnifying-glass" class="icon" />
</.button>
<.button size="icon-lg" variant="ghost" aria-label="Close">
<.icon name="hero-x-mark" class="icon" />
</.button>| Size | Dimensions | Icon Size | Use Case |
|---|---|---|---|
icon-xs | 28 x 28px | 14px | Very compact icon actions |
icon-sm | 32 x 32px | 16px | Small icon actions |
icon-md | 36 x 36px | 18px | Standard icon actions |
icon | 36 x 36px | 18px | Alias for icon-md |
icon-lg | 40 x 40px | 20px | Large icon actions |
icon-xl | 44 x 44px | 22px | Extra large icon actions |
Icons
Any icon placed inside the button slot is automatically sized and spaced based on the
button's size attribute. Always add the icon class to <.icon> so the size and
spacing rules can target it:
<.button size="lg" variant="solid" color="success">
<.icon name="hero-check-circle" class="icon" /> Order Confirmed
</.button>
<.button size="sm" variant="ghost" color="danger">
<.icon name="hero-trash" class="icon" /> Remove Item
</.button>
<.button size="icon" phx-click="toggle-sidebar" aria-label="Toggle sidebar">
<.icon name="hero-bars-3" class="icon" />
</.button>Icon class required
The icon class on <.icon> is required for automatic sizing, alignment, and the
subtle color de-emphasis applied to icons inside buttons.
<.button>
<.icon name="hero-check" class="icon" /> Confirm
</.button>Rendering as a Link
By default the component renders a <button> element. Pass any of href, navigate,
or patch and it renders a Phoenix <.link> (<a> element) instead, while keeping
the same styling:
<.button navigate={~p"/dashboard"} variant="solid" color="primary">
Go to Dashboard
</.button>
<.button href="https://example.com" target="_blank" rel="noopener" variant="soft">
External Link
</.button>
<.button patch={~p"/users?sort=name"} variant="ghost">
Sort by Name
</.button>When rendered as a link, the component forwards standard anchor attributes (target,
download, rel, hreflang, referrerpolicy) and Phoenix navigation attributes
(navigate, patch, href, replace, method, csrf_token). When rendered as a
button, it forwards standard button attributes (type, autofocus, form, formaction,
formmethod, formenctype, formnovalidate, formtarget, name, value).
Disabled State
Disabled buttons render with reduced opacity, no shadow, and no pointer events. For
the <button> element the native disabled attribute is used; for links rendered as
<a> the component sets data-disabled instead, since anchors do not have a native
disabled attribute:
<.button disabled>Cannot Click</.button>
<.button disabled variant="solid" color="primary">Submitting...</.button>
<.button disabled navigate={~p"/dashboard"}>Coming Soon</.button>Button Groups
Wrap related buttons in <.button_group> to render them as a single connected
segmented control. The group removes inner border radii on adjacent buttons, overlaps
their borders so they share an edge, and lifts the focused button above its siblings:
<.button_group>
<.button>Year</.button>
<.button>Month</.button>
<.button>Week</.button>
</.button_group>Mix text and icon-only buttons in a single group, for example a copy action with an alternate icon-only entry point:
<.button_group>
<.button variant="solid" color="info">Copy</.button>
<.button variant="solid" color="info" size="icon-md" aria-label="Copy with options">
<.icon name="hero-clipboard-document" class="icon" />
</.button>
</.button_group>Examples
Primary form action
<.button variant="solid" color="primary" size="lg" phx-click="submit-form">
<.icon name="hero-paper-airplane" class="icon" />
Submit Application
</.button>Destructive action with confirmation
<.button
variant="solid"
color="danger"
phx-click="delete_item"
phx-value-id={@item.id}
data-confirm="Are you sure? This cannot be undone."
>
<.icon name="hero-trash" class="icon" /> Delete Item
</.button>Navigation link styled as a button
<.button navigate={~p"/settings"} variant="ghost" size="sm">
<.icon name="hero-cog-6-tooth" class="icon" /> Account Settings
</.button>Icon-only toolbar action
<.button
size="icon"
variant="ghost"
phx-click="show-details"
phx-value-id={@user.id}
aria-label="View user details"
>
<.icon name="hero-eye" class="icon" />
</.button>Submit and cancel pair in a button group
<.button_group>
<.button phx-click="cancel">Cancel</.button>
<.button variant="solid" color="primary" type="submit">Save</.button>
</.button_group>
Summary
Components
Renders a button or link styled with the chosen variant, color, and size.
Renders a container that visually joins multiple buttons into a connected segmented unit.
Components
Renders a button or link styled with the chosen variant, color, and size.
Use this for click handlers, form submissions, and navigation. The component renders a
<button> by default and switches to a Phoenix <.link> (<a> element) when any of
href, navigate, or patch is provided, so the same call site can drive an action
or a route change. Variant, color, and size classes are merged with anything passed to
class, with later classes taking precedence.
Examples
<.button phx-click="save">Save Changes</.button>
<.button variant="solid" color="primary" size="lg">
<.icon name="hero-plus" class="icon" /> Create New
</.button>
<.button variant="ghost" color="danger" phx-click="delete">
<.icon name="hero-trash" class="icon" /> Delete
</.button>
<.button navigate={~p"/dashboard"} variant="soft" color="info">
Go to Dashboard
</.button>
<.button size="icon" variant="ghost" aria-label="Search">
<.icon name="hero-magnifying-glass" class="icon" />
</.button>Attributes
color(:string) - The semantic color of the button. Each color defines styles for every variant and is tuned for both light and dark modes through the design system tokens.primary: the most important action in context (save, submit, continue). Default.info: informational actions (view details, learn more).success: positive actions and confirmations (approve, mark complete).warning: actions that need extra attention (proceed despite a warning).danger: destructive or irreversible actions (delete, remove).
Defaults to
"primary". Must be one of"primary","danger","warning","success", or"info".size(:string) - Controls height, padding, font size, and the size of any nested<.icon>. Sizes prefixed withicon-render a square button tuned for icon-only content;iconis an alias foricon-md. Defaults to"md".Defaults to
"md". Must be one of"xs","sm","md","lg","xl","icon-xs","icon-sm","icon-md","icon","icon-lg", or"icon-xl".variant(:string) - The visual style of the button.solid: filled background, strongest visual weight. Use for the single primary action on a screen.soft: tinted background without a visible border. Use for secondary actions adjacent to a primary one.surface: tinted background with a colored border. Use for contained secondary actions that need a clearer boundary.outline: bordered with transparent background. Default. Use for general-purpose actions.dashed: dashed border with transparent background. Use for placeholder, draft, or "add" actions.ghost: no border or background until hover. Use for toolbar buttons and minimal utility actions.
Defaults to
"outline". Must be one of"solid","soft","surface","outline","dashed", or"ghost".disabled(:boolean) - When true, the button becomes non-interactive and renders with reduced opacity and no shadow. Buttons rendered as<button>use the nativedisabledattribute; buttons rendered as<a>(whenhref,navigate, orpatchis set) usedata-disabledinstead, since anchors have no nativedisabledattribute.Defaults to
false.class(:any) - Additional CSS classes appended to the button. Merged with the component's base, variant, color, and size classes, so utilities here override defaults where they conflict.Defaults to
nil.Global attributes are accepted. Additional HTML attributes forwarded to the underlying
<button>or<a>element. The component picks the element based on whetherhref,navigate, orpatchis present inrest, and accepts attributes valid for either: standard button attributes (type,autofocus,form,formaction,formmethod,formenctype,formnovalidate,formtarget,name,value), anchor attributes (target,download,rel,hreflang,referrerpolicy), and Phoenix navigation attributes (navigate,patch,href,replace,method,csrf_token). Supports all globals plus:["target", "download", "rel", "hreflang", "type", "referrerpolicy", "navigate", "patch", "href", "replace", "method", "csrf_token", "autofocus", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "type", "value"].
Slots
inner_block(required) - Content displayed inside the button. Accepts text,<.icon>elements, or both. Icons inside the slot are automatically sized and spaced based onsizeas long as they carry theiconclass.
Renders a container that visually joins multiple buttons into a connected segmented unit.
Use this to group related actions, such as a "Year/Month/Week" range selector or a
paired action with an icon-only secondary entry point. The group strips inner border
radii on adjacent buttons, overlaps their borders so they share an edge, and lifts
the focused button above its siblings so its focus ring is not clipped. Renders a
<div> container that wraps the grouped buttons.
Examples
<.button_group>
<.button>Year</.button>
<.button>Month</.button>
<.button>Week</.button>
</.button_group>Pair a labeled action with an icon-only companion:
<.button_group>
<.button variant="solid" color="info">Copy</.button>
<.button variant="solid" color="info" size="icon-md" aria-label="Copy with options">
<.icon name="hero-clipboard-document" class="icon" />
</.button>
</.button_group>Attributes
class(:any) - Additional CSS classes appended to the group container. Merged with the layout classes that produce the segmented appearance.Defaults to
nil.Global attributes are accepted. Additional HTML attributes forwarded to the group container
<div>.
Slots
inner_block(required) - The buttons to render as a connected group. Expects one or more<.button>children.