Fluxon.Components.Button (Fluxon v2.4.0-rc.2)

Provides <.button> and <.button_group> components for interactive actions and navigation.

This module offers a versatile button component that renders either a <button> or an <a> tag based on the provided attributes, making it suitable for user actions, form submissions, and navigation. It supports six visual variants, five semantic colors, multiple size options including dedicated icon-only sizes, and automatic icon scaling.

It also includes a <.button_group> component to visually join multiple buttons into a single connected unit.

Basic Usage

Render buttons for actions and interactions:

<.button>Default Button</.button>
<.button variant="solid" color="primary">Save</.button>
<.button variant="ghost">Cancel</.button>

Visual Variants

Choose from six visual styles based on emphasis needs:

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

Each variant is designed for specific use cases:

  • solid: Filled button with strongest visual weight, perfect for primary actions
  • soft: Subtle background without border, ideal for secondary actions
  • surface: Like soft but with a border, great for contained secondary actions
  • outline: Border with transparent background, good for alternative actions (default)
  • dashed: Dashed border with transparent background, useful for placeholder or draft actions
  • ghost: No border or background, minimal styling for utility actions

Semantic Colors

Use semantic colors to convey meaning and intent. Each color is designed for both light and dark modes:

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

Available colors and their common use cases:

  • primary: Most important actions (e.g., save, submit, continue)
  • info: Informational actions (e.g., view details, learn more)
  • success: Positive actions (e.g., confirm, approve)
  • warning: Actions that require attention (e.g., confirmation prompts)
  • danger: Destructive actions (e.g., delete, remove)

Size Variants

Scale buttons appropriately for different contexts:

<.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
xs28pxxs16pxCompact UI elements
sm32pxsm18pxSecondary actions
md36pxsm20pxDefault size
lg40pxsm22pxPrimary actions
xl44pxbase24pxHero sections, prominent calls to action

Icon-Only Sizes

Dedicated square sizes for icon-only buttons, ensuring the icon is centered:

<.button size="icon-sm">
  <.icon name="hero-pencil" class="icon" />
</.button>
<.button size="icon" variant="solid" color="primary">
  <.icon name="hero-magnifying-glass" class="icon" />
</.button>
<.button size="icon-lg" variant="ghost">
  <.icon name="hero-x-mark" class="icon" />
</.button>
SizeDimensionsIcon SizeUse Case
icon-xs28 x 28px16pxVery compact icon actions
icon-sm32 x 32px18pxSmall icon actions
icon-md36 x 36px20pxStandard icon actions
icon36 x 36px20pxAlias for icon-md
icon-lg40 x 40px22pxLarge icon actions
icon-xl44 x 44px24pxExtra large icon actions

With Icons

Icons placed inside the button slot are automatically sized and spaced based on the button's size attribute. Always add the icon class to <.icon> for correct scaling:

<.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">
  <.icon name="hero-bars-3" class="icon" />
</.button>

Icon Class Required

The icon class on <.icon> is required for automatic sizing and alignment:

<.button>
  <.icon name="hero-check" class="icon" /> Confirm
</.button>

The component renders as a <button> by default. When href, navigate, or patch is provided, it automatically renders as a Phoenix <.link> (<a> tag) instead:

<.button navigate={~p"/dashboard"} variant="solid" color="primary">
  Go to Dashboard
</.button>

<.button href="https://example.com" target="_blank" variant="soft">
  External Link
</.button>

<.button patch={~p"/users?sort=name"} variant="ghost">
  Sort by Name
</.button>

When rendered as a link, it supports all standard anchor attributes (target, rel, etc.) and Phoenix LiveView navigation attributes (navigate, patch, replace, method, csrf_token).

When rendered as a button, it supports standard button attributes (type, disabled, form, phx-click, etc.).

Disabled State

Disabled buttons have reduced opacity, no shadow, and are non-interactive. For <button> elements, the native disabled attribute is used. For links, data-disabled is applied instead:

<.button disabled>Cannot Click</.button>
<.button disabled variant="solid" color="primary">Submitting...</.button>

Button Groups

Use <.button_group> to join multiple buttons into a connected unit. The group removes inner border radii and overlaps borders so buttons appear seamless:

<.button_group>
  <.button>Year</.button>
  <.button>Month</.button>
  <.button>Week</.button>
</.button_group>

<.button_group>
  <.button variant="solid" color="info">Copy</.button>
  <.button variant="solid" color="info" size="icon-md">
    <.icon name="hero-clipboard-document" class="icon" />
  </.button>
</.button_group>

Accessibility

The button component follows accessibility best practices:

  • Renders semantic <button> or <a> elements as appropriate
  • Includes visible focus ring styling via focus-visible for keyboard navigation
  • Disabled state uses the native disabled attribute (buttons) or data-disabled (links) with pointer-events-none to prevent interaction
  • For icon-only buttons, add aria-label to provide an accessible name:
<.button size="icon" variant="ghost" aria-label="Close sidebar">
  <.icon name="hero-x-mark" class="icon" />
</.button>

Common Patterns

Primary Action

<.button variant="solid" color="primary" size="lg" phx-click="submit-form">
  <.icon name="hero-paper-airplane" class="icon" />
  Submit Application
</.button>

Danger Action with Confirmation

<.button
  variant="solid"
  color="danger"
  phx-click="delete_item"
  phx-value-id={@item.id}
  phx-confirm="Are you sure?"
>
  <.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 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>

Summary

Components

Renders a button or link element with customizable variant, color, and size.

Renders a container that visually joins multiple buttons into a connected unit.

Components

button(assigns)

Renders a button or link element with customizable variant, color, and size.

Automatically renders a <button> element by default, or a Phoenix <.link> (<a> tag) when href, navigate, or patch is provided. All variant, color, and size styles are merged with any custom classes via class.

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 scheme of the button. Each color includes specific styles for all variants and maintains proper contrast in both light and dark modes. Available options: primary, danger, warning, success, info.

    Defaults to "primary".

  • size (:string) - The size variant of the button. Affects height, padding, font size, and icon sizing. Defaults to "md".

  • variant (:string) - The visual style variant of the button:

    • solid: Filled button with strongest visual weight (primary actions).
    • soft: Subtle background without border (secondary actions).
    • surface: Like soft but with border (contained secondary actions).
    • outline: Border with transparent background (alternative actions, default).
    • dashed: Dashed border with transparent background (placeholder/draft actions).
    • ghost: No border or background, minimal styling (utility actions).

    Defaults to "outline".

  • disabled (:boolean) - Whether the button is disabled. When true, the button becomes non-interactive. Defaults to false.

  • class (:any) - Additional CSS classes to be applied to the button. These are merged with the component's base classes, variant styles, and size styles.

    Defaults to nil.

  • Global attributes are accepted. Additional HTML attributes to apply to the underlying <button> or <a> element. The component automatically determines whether to render a button or an anchor based on the presence of href, navigate, or patch attributes. It supports attributes relevant to both element types. 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) - The content to be displayed within the button. Supports text and icons with automatic spacing and sizing based on the selected size variant.

button_group(assigns)

Renders a container that visually joins multiple buttons into a connected unit.

The group removes inner border radii, overlaps borders between adjacent buttons, and ensures focused buttons appear above their siblings via z-index. It renders a <div> with role="group" for accessibility.

Examples

<.button_group>
  <.button>Year</.button>
  <.button>Month</.button>
  <.button>Week</.button>
</.button_group>

Combine text and icon-only buttons in a single group:

<.button_group>
  <.button variant="solid" color="info">Copy</.button>
  <.button variant="solid" color="info" size="icon-md">
    <.icon name="hero-clipboard-document" class="icon" />
  </.button>
</.button_group>

Attributes

  • class (:any) - Additional CSS classes for the group container. Defaults to nil.
  • Global attributes are accepted. Additional HTML attributes for the group container.

Slots

  • inner_block (required) - The slot for the buttons to be grouped.