Action Icon

v0.0.10

v0.0.10StableHeadlessStatelessAccessibleApache-2.0
Installation mix mishka.ui.gen.headless action_icon
Source View Source

Overview of the Phoenix and LiveView Headless Action Icon Component

The Mishka Chelekom Headless Action Icon is an icon-only button for Phoenix and LiveView templates. It renders one button and no styling. A button with no visible text needs a name, so label is required and becomes its aria-label. The icon, an SVG or a glyph, goes in the default slot.

disabled sets the native disabled attribute and a data-disabled attribute, so you can style the state with data-[disabled]: variants. type is button by default and accepts submit and reset. There are no inner parts: style the root through class. It also carries a stable chelekom-action-icon class. For a button with a text label, a loading state or link behavior, use the headless Button.

Base UI Action Icon example - edit and delete buttons (Phoenix headless)

Base UI Action Icon example - edit and delete buttons (Phoenix headless)

heex
<div class="flex items-center gap-3">
  <.action_icon
    label="Edit"
    class="inline-flex size-9 items-center justify-center rounded-md text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-800"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 24"
      stroke-width="1.5"
      stroke="currentColor"
      class="size-5"
    >
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125"
      />
    </svg>
  </.action_icon>
  <.action_icon
    label="Delete"
    disabled
    class="inline-flex size-9 items-center justify-center rounded-md text-neutral-700 data-[disabled]:opacity-40 dark:text-neutral-300"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 24"
      stroke-width="1.5"
      stroke="currentColor"
      class="size-5"
    >
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
      />
    </svg>
  </.action_icon>
</div>

Click handling and forms

Events go through the global attributes. Put phx-click, phx-value-* or a JS command straight on the component. form, name and value are accepted too, so an action icon with type="submit" can submit a form it does not sit inside.

heex
<.action_icon
  label="Delete invoice"
  phx-click="delete"
  phx-value-id={invoice.id}
  class="rounded-md p-2 hover:bg-neutral-100"
>
  <.icon name="hero-trash" class="size-5" />
</.action_icon>
heex
<.action_icon label="Save changes" type="submit" form="settings-form" class="rounded-md p-2 hover:bg-neutral-100">
  <.icon name="hero-check" class="size-5" />
</.action_icon>

Parts & data attributes

The root is a button with aria-label, disabled and data-disabled. The slot content is rendered directly inside it, with no wrapper element.

Accessibility

Follows the WAI-ARIA Button pattern: Enter and Space activate the button, and label is its accessible name. A disabled action icon uses the native attribute, so it leaves the tab order and does not fire clicks.