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 as soft plus 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>
SizeHeightTextIcon SizeUse Case
xs28pxxs14pxCompact UI, dense tables, inline controls
sm32pxsm16pxSecondary actions, toolbar buttons
md36pxsm16pxDefault. Most form and page actions
lg40pxsm18pxPrimary actions on form-heavy pages
xl44pxbase20pxHero 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>
SizeDimensionsIcon SizeUse Case
icon-xs28 x 28px14pxVery compact icon actions
icon-sm32 x 32px16pxSmall icon actions
icon-md36 x 36px18pxStandard icon actions
icon36 x 36px18pxAlias for icon-md
icon-lg40 x 40px20pxLarge icon actions
icon-xl44 x 44px22pxExtra 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>

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>
<.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

button(assigns)

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 with icon- render a square button tuned for icon-only content; icon is an alias for icon-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 native disabled attribute; buttons rendered as <a> (when href, navigate, or patch is set) use data-disabled instead, since anchors have no native disabled attribute.

    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 whether href, navigate, or patch is present in rest, 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 on size as long as they carry the icon class.

button_group(assigns)

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.