---
title: Icon
description: SVG icon with preset support
visibility: guest
draft: false
---

# Icon

The `<x-wirekit::icon />` component renders SVG icons via semantic aliases. Instead of referencing a specific icon set directly, you use abstract names like `close`, `search`, or `trash`. WireKit maps these to the actual icon from your configured preset — switch icon sets with a single config change.

## Requirements

The icon system requires [blade-icons](https://github.com/blade-ui-kit/blade-icons) (the rendering engine) and one icon set package (the actual SVGs):

```bash
# Required: blade-icons rendering engine
composer require blade-ui-kit/blade-icons

# Plus ONE icon set — choose your favorite:
composer require blade-ui-kit/blade-heroicons          # Heroicons (default)
composer require mallardduck/blade-lucide-icons        # Lucide
composer require codeat3/blade-phosphor-icons          # Phosphor
composer require secondnetwork/blade-tabler-icons     # Tabler
```

::: tip
You only need **one** icon set installed. WireKit's default preset is `heroicons`, so `blade-ui-kit/blade-heroicons` is the quickest way to get started. One stackable extension preset (`heroicons-marketing`) reuses the same package and layers a handful of marketing-copy aliases on top; a second (`heroicons-app`) is registered but empty — see [Available Presets](#available-presets) for the full menu.
:::

### When a package is missing

Both halves have to be there, and the failure looks different depending on which one is
absent. Neither takes the page down.

| Installed | What renders | What you are told |
| --- | --- | --- |
| Neither | an inert, correctly-sized placeholder | one warning in the log naming both packages |
| `blade-icons` only | an inert, correctly-sized placeholder | one error in the log naming the set package to install |
| Both | the icon | nothing |

The middle row is the one worth knowing about, because it is the state an application
lands in by accident. If you already had `blade-icons` for your own icon set, the set
package above reads as optional — and every WireKit alias resolves against it. `inbox`
becomes `heroicon-m-inbox` whether or not Heroicons is installed, because the alias
tables are static.

The placeholder keeps its box, so the layout does not move, and it carries
`data-wk-icon-missing="<alias>"` if you want to find them in a rendered page. The log
line names the resolved identifier rather than the alias you wrote, because the alias is
not the problem:

```text
WireKit: the icon alias 'inbox' resolved to 'heroicon-m-inbox', but no icon set with the
prefix 'heroicon' is registered. Install blade-ui-kit/blade-heroicons to provide it.
Rendering an empty placeholder.
```

It is said once per prefix per process, not once per icon — a single page draws icons
through buttons, dropdowns and modals, and fifty identical lines is a log nobody reads.

Two deliberate exceptions to the degradation:

- **A console command or a test fails loudly instead.** There, a missing package is a
  build problem somebody can fix now, and a silent placeholder would let it ship. Set
  `wirekit.validation.throw_on_invalid` to force either behavior in either context.
- **A fallback you configured still wins.** If `blade-icons` has a fallback icon
  configured — per set or globally — that icon renders and WireKit never sees a failure.

## Usage

:::preview{title="Navigation and Action Icons"}
<x-wirekit::row gap="lg">
    <x-wirekit::icon name="close" />
    <x-wirekit::icon name="menu" />
    <x-wirekit::icon name="search" />
    <x-wirekit::icon name="chevron-down" />
    <x-wirekit::icon name="chevron-up" />
    <x-wirekit::icon name="chevron-left" />
    <x-wirekit::icon name="chevron-right" />
    <x-wirekit::icon name="check" />
    <x-wirekit::icon name="plus" />
    <x-wirekit::icon name="minus" />
</x-wirekit::row>
:::

:::preview{title="Status and Feedback Icons"}
<x-wirekit::row gap="lg">
    <x-wirekit::icon name="info" />
    <x-wirekit::icon name="success" />
    <x-wirekit::icon name="warning" />
    <x-wirekit::icon name="danger" />
</x-wirekit::row>
:::

:::preview{title="Object and Visibility Icons"}
<x-wirekit::row wrap gap="lg">
    <x-wirekit::icon name="user" />
    <x-wirekit::icon name="calendar" />
    <x-wirekit::icon name="trash" />
    <x-wirekit::icon name="edit" />
    <x-wirekit::icon name="eye" />
    <x-wirekit::icon name="eye-off" />
    <x-wirekit::icon name="upload" />
    <x-wirekit::icon name="download" />
    <x-wirekit::icon name="sort-asc" />
    <x-wirekit::icon name="sort-desc" />
    <x-wirekit::icon name="filter" />
    <x-wirekit::icon name="external-link" />
</x-wirekit::row>
:::

```blade
<!-- Default size (h-5 w-5) -->
<x-wirekit::icon name="close" />

<!-- Custom size -->
<x-wirekit::icon name="search" class="h-4 w-4" />

<!-- Decorative icon (hidden from screen readers — the default) -->
<x-wirekit::icon name="trash" class="h-4 w-4" />
```

## Icon Preview

Every semantic alias rendered with the default **Heroicons** preset:

:::preview{title="All Semantic Icons"}
<x-wirekit::row wrap gap="md">
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="close" />
        <x-wirekit::text size="xs" variant="muted">close</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="menu" />
        <x-wirekit::text size="xs" variant="muted">menu</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="search" />
        <x-wirekit::text size="xs" variant="muted">search</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="click" />
        <x-wirekit::text size="xs" variant="muted">click</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="paint-brush" />
        <x-wirekit::text size="xs" variant="muted">paint-brush</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chevron-down" />
        <x-wirekit::text size="xs" variant="muted">chevron-down</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chevron-up" />
        <x-wirekit::text size="xs" variant="muted">chevron-up</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chevron-left" />
        <x-wirekit::text size="xs" variant="muted">chevron-left</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chevron-right" />
        <x-wirekit::text size="xs" variant="muted">chevron-right</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="check" />
        <x-wirekit::text size="xs" variant="muted">check</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="plus" />
        <x-wirekit::text size="xs" variant="muted">plus</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="minus" />
        <x-wirekit::text size="xs" variant="muted">minus</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="info" />
        <x-wirekit::text size="xs" variant="muted">info</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="success" />
        <x-wirekit::text size="xs" variant="muted">success</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="warning" />
        <x-wirekit::text size="xs" variant="muted">warning</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="danger" />
        <x-wirekit::text size="xs" variant="muted">danger</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="user" />
        <x-wirekit::text size="xs" variant="muted">user</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="calendar" />
        <x-wirekit::text size="xs" variant="muted">calendar</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="trash" />
        <x-wirekit::text size="xs" variant="muted">trash</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="edit" />
        <x-wirekit::text size="xs" variant="muted">edit</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="eye" />
        <x-wirekit::text size="xs" variant="muted">eye</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="eye-off" />
        <x-wirekit::text size="xs" variant="muted">eye-off</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="upload" />
        <x-wirekit::text size="xs" variant="muted">upload</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="download" />
        <x-wirekit::text size="xs" variant="muted">download</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sort-asc" />
        <x-wirekit::text size="xs" variant="muted">sort-asc</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sort-desc" />
        <x-wirekit::text size="xs" variant="muted">sort-desc</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="filter" />
        <x-wirekit::text size="xs" variant="muted">filter</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="external-link" />
        <x-wirekit::text size="xs" variant="muted">external-link</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="home" />
        <x-wirekit::text size="xs" variant="muted">home</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="moon" />
        <x-wirekit::text size="xs" variant="muted">moon</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sun" />
        <x-wirekit::text size="xs" variant="muted">sun</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="system" />
        <x-wirekit::text size="xs" variant="muted">system</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="code" />
        <x-wirekit::text size="xs" variant="muted">code</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="key" />
        <x-wirekit::text size="xs" variant="muted">key</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="rocket-launch" />
        <x-wirekit::text size="xs" variant="muted">rocket-launch</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="broadcast" />
        <x-wirekit::text size="xs" variant="muted">broadcast</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chart-bar" />
        <x-wirekit::text size="xs" variant="muted">chart-bar</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="coins" />
        <x-wirekit::text size="xs" variant="muted">coins</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="gift" />
        <x-wirekit::text size="xs" variant="muted">gift</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="list-bullets" />
        <x-wirekit::text size="xs" variant="muted">list-bullets</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="list-checks" />
        <x-wirekit::text size="xs" variant="muted">list-checks</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="lock-key" />
        <x-wirekit::text size="xs" variant="muted">lock-key</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="map-pin" />
        <x-wirekit::text size="xs" variant="muted">map-pin</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="percent" />
        <x-wirekit::text size="xs" variant="muted">percent</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sliders" />
        <x-wirekit::text size="xs" variant="muted">sliders</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="trend-up" />
        <x-wirekit::text size="xs" variant="muted">trend-up</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chart-line" />
        <x-wirekit::text size="xs" variant="muted">chart-line</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="folders" />
        <x-wirekit::text size="xs" variant="muted">folders</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="phone" />
        <x-wirekit::text size="xs" variant="muted">phone</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="book-open" />
        <x-wirekit::text size="xs" variant="muted">book-open</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sign-out" />
        <x-wirekit::text size="xs" variant="muted">sign-out</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="megaphone" />
        <x-wirekit::text size="xs" variant="muted">megaphone</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="map" />
        <x-wirekit::text size="xs" variant="muted">map</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="file-text" />
        <x-wirekit::text size="xs" variant="muted">file-text</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="copy" />
        <x-wirekit::text size="xs" variant="muted">copy</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="globe" />
        <x-wirekit::text size="xs" variant="muted">globe</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="book" />
        <x-wirekit::text size="xs" variant="muted">book</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="lightbulb" />
        <x-wirekit::text size="xs" variant="muted">lightbulb</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="settings" />
        <x-wirekit::text size="xs" variant="muted">settings</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="gear" />
        <x-wirekit::text size="xs" variant="muted">gear</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="dashboard" />
        <x-wirekit::text size="xs" variant="muted">dashboard</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="billing" />
        <x-wirekit::text size="xs" variant="muted">billing</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="credit-card" />
        <x-wirekit::text size="xs" variant="muted">credit-card</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="server" />
        <x-wirekit::text size="xs" variant="muted">server</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="database" />
        <x-wirekit::text size="xs" variant="muted">database</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="cloud" />
        <x-wirekit::text size="xs" variant="muted">cloud</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="shield-check" />
        <x-wirekit::text size="xs" variant="muted">shield-check</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="inbox" />
        <x-wirekit::text size="xs" variant="muted">inbox</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="refresh" />
        <x-wirekit::text size="xs" variant="muted">refresh</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="undo" />
        <x-wirekit::text size="xs" variant="muted">undo</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="play" />
        <x-wirekit::text size="xs" variant="muted">play</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="pause" />
        <x-wirekit::text size="xs" variant="muted">pause</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="stop" />
        <x-wirekit::text size="xs" variant="muted">stop</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="speaker" />
        <x-wirekit::text size="xs" variant="muted">speaker</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="mute" />
        <x-wirekit::text size="xs" variant="muted">mute</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="microphone" />
        <x-wirekit::text size="xs" variant="muted">microphone</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="users" />
        <x-wirekit::text size="xs" variant="muted">users</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="history" />
        <x-wirekit::text size="xs" variant="muted">history</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="legal" />
        <x-wirekit::text size="xs" variant="muted">legal</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="badge" />
        <x-wirekit::text size="xs" variant="muted">badge</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="layers" />
        <x-wirekit::text size="xs" variant="muted">layers</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="stack" />
        <x-wirekit::text size="xs" variant="muted">stack</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="cash-register" />
        <x-wirekit::text size="xs" variant="muted">cash-register</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="bell-slash" />
        <x-wirekit::text size="xs" variant="muted">bell-slash</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="tag" />
        <x-wirekit::text size="xs" variant="muted">tag</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="send" />
        <x-wirekit::text size="xs" variant="muted">send</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="envelope" />
        <x-wirekit::text size="xs" variant="muted">envelope</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="store" />
        <x-wirekit::text size="xs" variant="muted">store</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="cart" />
        <x-wirekit::text size="xs" variant="muted">cart</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="receipt" />
        <x-wirekit::text size="xs" variant="muted">receipt</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="truck" />
        <x-wirekit::text size="xs" variant="muted">truck</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="package" />
        <x-wirekit::text size="xs" variant="muted">package</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="barcode" />
        <x-wirekit::text size="xs" variant="muted">barcode</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="user-add" />
        <x-wirekit::text size="xs" variant="muted">user-add</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="user-remove" />
        <x-wirekit::text size="xs" variant="muted">user-remove</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="building" />
        <x-wirekit::text size="xs" variant="muted">building</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="webhook" />
        <x-wirekit::text size="xs" variant="muted">webhook</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrow-left" />
        <x-wirekit::text size="xs" variant="muted">arrow-left</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="clock" />
        <x-wirekit::text size="xs" variant="muted">clock</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="lock" />
        <x-wirekit::text size="xs" variant="muted">lock</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="archive" />
        <x-wirekit::text size="xs" variant="muted">archive</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="image" />
        <x-wirekit::text size="xs" variant="muted">image</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="message" />
        <x-wirekit::text size="xs" variant="muted">message</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="reply" />
        <x-wirekit::text size="xs" variant="muted">reply</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="forward" />
        <x-wirekit::text size="xs" variant="muted">forward</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="bell" />
        <x-wirekit::text size="xs" variant="muted">bell</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="bolt" />
        <x-wirekit::text size="xs" variant="muted">bolt</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="shield" />
        <x-wirekit::text size="xs" variant="muted">shield</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="more" />
        <x-wirekit::text size="xs" variant="muted">more</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chevron-up-down" />
        <x-wirekit::text size="xs" variant="muted">chevron-up-down</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="more-vertical" />
        <x-wirekit::text size="xs" variant="muted">more-vertical</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrows-left-right" />
        <x-wirekit::text size="xs" variant="muted">arrows-left-right</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="hash" />
        <x-wirekit::text size="xs" variant="muted">hash</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="shield-warning" />
        <x-wirekit::text size="xs" variant="muted">shield-warning</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="prohibit" />
        <x-wirekit::text size="xs" variant="muted">prohibit</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="scan" />
        <x-wirekit::text size="xs" variant="muted">scan</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrow-down" />
        <x-wirekit::text size="xs" variant="muted">arrow-down</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrow-right" />
        <x-wirekit::text size="xs" variant="muted">arrow-right</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrow-up" />
        <x-wirekit::text size="xs" variant="muted">arrow-up</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="arrow-up-right" />
        <x-wirekit::text size="xs" variant="muted">arrow-up-right</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="chart-pie" />
        <x-wirekit::text size="xs" variant="muted">chart-pie</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="code-bracket" />
        <x-wirekit::text size="xs" variant="muted">code-bracket</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="cog-6-tooth" />
        <x-wirekit::text size="xs" variant="muted">cog-6-tooth</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="command-line" />
        <x-wirekit::text size="xs" variant="muted">command-line</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="finger-print" />
        <x-wirekit::text size="xs" variant="muted">finger-print</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="fire" />
        <x-wirekit::text size="xs" variant="muted">fire</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="heart" />
        <x-wirekit::text size="xs" variant="muted">heart</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="attach" />
        <x-wirekit::text size="xs" variant="muted">attach</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="cube" />
        <x-wirekit::text size="xs" variant="muted">cube</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="sparkles" />
        <x-wirekit::text size="xs" variant="muted">sparkles</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="link" />
        <x-wirekit::text size="xs" variant="muted">link</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="live" />
        <x-wirekit::text size="xs" variant="muted">live</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="lock-closed" />
        <x-wirekit::text size="xs" variant="muted">lock-closed</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="open-source" />
        <x-wirekit::text size="xs" variant="muted">open-source</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="puzzle-piece" />
        <x-wirekit::text size="xs" variant="muted">puzzle-piece</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="security" />
        <x-wirekit::text size="xs" variant="muted">security</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="speed" />
        <x-wirekit::text size="xs" variant="muted">speed</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="squares-2x2" />
        <x-wirekit::text size="xs" variant="muted">squares-2x2</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="star" />
        <x-wirekit::text size="xs" variant="muted">star</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="swatch" />
        <x-wirekit::text size="xs" variant="muted">swatch</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="unlock" />
        <x-wirekit::text size="xs" variant="muted">unlock</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="user-group" />
        <x-wirekit::text size="xs" variant="muted">user-group</x-wirekit::text>
    </x-wirekit::stack>
    <x-wirekit::stack align="center" gap="xs" style="width: 6.5rem">
        <x-wirekit::icon name="x-circle" />
        <x-wirekit::text size="xs" variant="muted">x-circle</x-wirekit::text>
    </x-wirekit::stack>
</x-wirekit::row>
:::

## Configuration

Configure your icon preset in `config/wirekit.php`. Use the singular `preset` key for a single base preset, or the plural `presets` array to stack a base preset with one or more stackable extension presets:

```php
// Single base preset (the simplest case)
'icons' => [
    'preset' => 'heroicons',  // or 'lucide', 'phosphor', 'tabler'
    'aliases' => [],
],

// Stacked: base + the marketing extension (adds its marketing-copy aliases)
'icons' => [
    'presets' => ['heroicons', 'heroicons-marketing'],
    'aliases' => [],
],
```

See [Available Presets](#available-presets) for the full preset list including the stackable extension.

## Available Presets

WireKit ships with four base presets, each mapping the full semantic-alias set. Two extension presets are also registered; only `heroicons-marketing` still carries aliases, and both resolve to heroicons glyphs, so they belong on a heroicons install rather than on lucide, phosphor or tabler.

| Preset Key | Type | Icon Set | Aliases | Blade Package | Browse Icons |
| --- | --- | --- | --- | --- | --- |
| `heroicons` | Base | Heroicons (Mini 20px) | Full set | [`blade-ui-kit/blade-heroicons`](https://github.com/blade-ui-kit/blade-heroicons) | [heroicons.com](https://heroicons.com) |
| `heroicons-app` | Stackable | Heroicons (Mini 20px) | **none — empty since v2.37.0** | [`blade-ui-kit/blade-heroicons`](https://github.com/blade-ui-kit/blade-heroicons) | [heroicons.com](https://heroicons.com) |
| `heroicons-marketing` | Stackable | Heroicons (Mini 20px) | Marketing extras | [`blade-ui-kit/blade-heroicons`](https://github.com/blade-ui-kit/blade-heroicons) | [heroicons.com](https://heroicons.com) |
| `lucide` | Base | Lucide (Outline) | Full set | [`mallardduck/blade-lucide-icons`](https://github.com/mallardduck/blade-lucide-icons) | [lucide.dev](https://lucide.dev) |
| `phosphor` | Base | Phosphor (Regular) | Full set | [`codeat3/blade-phosphor-icons`](https://github.com/codeat3/blade-phosphor-icons) | [phosphoricons.com](https://phosphoricons.com) |
| `tabler` | Base | Tabler Icons | Full set | [`secondnetwork/blade-tabler-icons`](https://github.com/secondnetwork/blade-tabler-icons) | [tabler.io/icons](https://tabler.io/icons) |

### Stackable Presets (App + Marketing Aliases)

WireKit ships two stackable extension presets that compose with the base `heroicons` preset (or any base preset) without breaking the base alias contract:

- **`heroicons-app`** — **empty since 2026-08-26.** Every alias it carried now lives in
  all four base presets, so those words work on Lucide, Phosphor and Tabler too. It stays
  registered so a published config naming it still boots; stacking it is a no-op.
- **`heroicons-marketing`** — `cursor-arrow-rays`, `cube-transparent`, `a11y`, `sparkle`, `ai`, `pulse`.
  These are the ones that could NOT move: either no set outside Heroicons has a genuine
  glyph for them, or the glyph it does have is already another alias's picture there —
  and a word that quietly means something else on a different set is worse than a word
  that is simply absent.

An alias can move from a stackable preset into the base set — several have — so the lists above
name the shape rather than the whole. `php artisan wirekit:icons --preset=heroicons-marketing` prints
the current set for the presets you actually have configured.

Activate by switching from the singular `preset` key to the plural `presets` array — stack as many extensions as you need:

```php
'icons' => [
    // 'preset' => 'heroicons',
    'presets' => ['heroicons', 'heroicons-marketing'],
    'aliases' => [],
],
```

Resolution order — highest priority first:

1. Developer `aliases` overrides
2. Right-most preset in the `presets` array (later wins)
3. …
4. Left-most preset in the `presets` array

Aliases in `heroicons-marketing` have **zero overlap** with the base `heroicons` preset (`heroicons-app` is empty, so it trivially overlaps nothing). The order is only meaningful when you stack presets that DO share alias names (e.g. `['heroicons', 'lucide']` — `lucide` would win on `close`, `search`, etc.). Anti-drift tests in `IconSystemTest` enforce both no-overlap guarantees.

```blade
{{-- 1. `arrow-up` needs no extension since v2.37.0 — it is in every base preset: --}}
<x-wirekit::icon name="arrow-up" />      {{-- table sort --}}

{{-- 2. After activating heroicons-marketing: --}}
<x-wirekit::icon name="sparkles" />
```

**Names move down, not away.** `lock`, `bell`, `lightbulb`, `bolt`, `rocket-launch` and `shield` were on this list and are now in the base preset — they resolve without activating anything. Nothing broke for anyone who had stacked a preset to get them; the extension simply no longer needs to carry the name. If a name you rely on is missing from a preset after an upgrade, look for it in the base tables above before assuming it is gone.

### Switching Presets

To switch from one **base** preset to another (e.g. Heroicons → Lucide):

1. Install the new icon package:

```bash
composer require mallardduck/blade-lucide-icons
```

2. Update your config:

```php
'icons' => [
    'preset' => 'lucide',
],
```

All WireKit components now use Lucide icons — no template changes needed.

To **add** the stackable extension preset `heroicons-marketing` on top of an existing base preset, switch from the singular `preset` key to the plural `presets` array — see the [Stackable Presets](#stackable-presets-app--marketing-aliases) section below for the full pattern. No additional Composer install is needed; it reuses the `blade-ui-kit/blade-heroicons` package the base `heroicons` preset already requires. (`heroicons-app` is still a valid preset name so an older published config keeps booting, but it is empty — stacking it changes nothing.)

## Semantic Aliases

WireKit defines a set of abstract icon names. Every **base** preset (`heroicons`, `lucide`, `phosphor`, `tabler`) maps the complete set. The **stackable extension** preset `heroicons-marketing` instead adds its own aliases on top of a base — see the [Available Presets](#available-presets) section for the per-preset alias counts.

The tables below list **every** alias against **every** base preset — one abstract name, four identifiers, so you can look a word up on whichever preset your project is actually configured for. Completeness here is checked rather than promised, in both directions: a test compares every cell against the presets and fails the build when an alias exists in the package and not on this page, and a second one fails when a base preset has no column at all.

For the authoritative list, ask the package rather than this page:

```bash
# 1. Every alias in every configured preset, grouped by preset.
php artisan wirekit:icons

# 2. Just the names, one per line — pipe it into a grep when you are
#    looking for whether a particular alias exists.
php artisan wirekit:icons --as=aliases

# 3. One preset only, as JSON, for tooling.
php artisan wirekit:icons --preset=heroicons --as=json
```

That command reads the presets your application has configured, so it is right for *your* install and cannot go stale the way a hand-maintained table does — this one had drifted well short of the real set before anyone noticed.

### Navigation and Actions

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `close` | Modal close, dismiss | `heroicon-m-x-mark` | `lucide-x` | `phosphor-x` | `tabler-x` |
| `menu` | Mobile nav toggle | `heroicon-m-bars-3` | `lucide-menu` | `phosphor-list` | `tabler-menu-2` |
| `search` | Search input | `heroicon-m-magnifying-glass` | `lucide-search` | `phosphor-magnifying-glass` | `tabler-search` |
| `click` | A pointer acting on something — call to action, interactive hint | `heroicon-m-cursor-arrow-rays` | `lucide-mouse-pointer-click` | `phosphor-cursor-click` | `tabler-click` |
| `chevron-down` | Select, dropdown | `heroicon-m-chevron-down` | `lucide-chevron-down` | `phosphor-caret-down` | `tabler-chevron-down` |
| `chevron-up` | Accordion toggle | `heroicon-m-chevron-up` | `lucide-chevron-up` | `phosphor-caret-up` | `tabler-chevron-up` |
| `chevron-left` | Pagination, back | `heroicon-m-chevron-left` | `lucide-chevron-left` | `phosphor-caret-left` | `tabler-chevron-left` |
| `chevron-right` | Pagination, forward | `heroicon-m-chevron-right` | `lucide-chevron-right` | `phosphor-caret-right` | `tabler-chevron-right` |
| `check` | Checkbox, success | `heroicon-m-check` | `lucide-check` | `phosphor-check` | `tabler-check` |
| `plus` | Add button | `heroicon-m-plus` | `lucide-plus` | `phosphor-plus` | `tabler-plus` |
| `minus` | Remove, collapse | `heroicon-m-minus` | `lucide-minus` | `phosphor-minus` | `tabler-minus` |
| `more` | Overflow menu — the actions a row keeps out of sight | `heroicon-m-ellipsis-horizontal` | `lucide-ellipsis` | `phosphor-dots-three` | `tabler-dots` |
| `chevron-up-down` | A pop-up button: shows the current choice, opens the others | `heroicon-m-chevron-up-down` | `lucide-chevrons-up-down` | `phosphor-caret-up-down` | `tabler-caret-up-down` |
| `more-vertical` | Overflow menu on its vertical axis, the usual row-action trigger | `heroicon-m-ellipsis-vertical` | `lucide-ellipsis-vertical` | `phosphor-dots-three-vertical` | `tabler-dots-vertical` |
| `arrows-left-right` | Swap, transfer, move between two sides | `heroicon-m-arrows-right-left` | `lucide-arrow-left-right` | `phosphor-arrows-left-right` | `tabler-arrows-left-right` |
| `hash` | An identifier, a channel, a tag | `heroicon-m-hashtag` | `lucide-hash` | `phosphor-hash` | `tabler-hash` |
| `shield-warning` | A protection that needs attention | `heroicon-m-shield-exclamation` | `lucide-shield-alert` | `phosphor-shield-warning` | `tabler-shield-exclamation` |
| `prohibit` | Blocked, not permitted | `heroicon-m-no-symbol` | `lucide-ban` | `phosphor-prohibit` | `tabler-ban` |
| `scan` | Scan a code, frame a subject | `heroicon-m-viewfinder-circle` | `lucide-scan` | `phosphor-scan` | `tabler-scan` |

### Status and Feedback

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `info` | Info alert | `heroicon-m-information-circle` | `lucide-info` | `phosphor-info` | `tabler-info-circle` |
| `success` | Success alert | `heroicon-m-check-circle` | `lucide-check-circle-2` | `phosphor-check-circle` | `tabler-circle-check` |
| `warning` | Warning alert | `heroicon-m-exclamation-triangle` | `lucide-alert-triangle` | `phosphor-warning` | `tabler-alert-triangle` |
| `danger` | Error/danger alert | `heroicon-m-x-circle` | `lucide-x-circle` | `phosphor-x-circle` | `tabler-circle-x` |

::: info
The four status names (`info`, `success`, `warning`, `danger`) are intentionally shared between this icon namespace and the canonical [intent values](/variants-and-intents) on components like `<x-wirekit::badge>` and `<x-wirekit::alert>`. Use `<x-wirekit::icon name="info">` next to `<x-wirekit::badge intent="info">` and both read identically across every theme preset. The shared keyword is a feature, not a namespace collision.
:::

### Objects and Visibility

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `user` | Avatar fallback | `heroicon-m-user` | `lucide-user` | `phosphor-user` | `tabler-user` |
| `calendar` | Datepicker | `heroicon-m-calendar` | `lucide-calendar` | `phosphor-calendar-blank` | `tabler-calendar` |
| `trash` | Delete action | `heroicon-m-trash` | `lucide-trash-2` | `phosphor-trash` | `tabler-trash` |
| `edit` | Edit action | `heroicon-m-pencil-square` | `lucide-pencil` | `phosphor-pencil-simple` | `tabler-edit` |
| `eye` | Show/reveal | `heroicon-m-eye` | `lucide-eye` | `phosphor-eye` | `tabler-eye` |
| `eye-off` | Hide/password toggle | `heroicon-m-eye-slash` | `lucide-eye-off` | `phosphor-eye-slash` | `tabler-eye-off` |
| `upload` | File upload | `heroicon-m-arrow-up-tray` | `lucide-upload` | `phosphor-upload-simple` | `tabler-upload` |
| `download` | File download | `heroicon-m-arrow-down-tray` | `lucide-download` | `phosphor-download-simple` | `tabler-download` |
| `sort-asc` | Table sort ascending | `heroicon-m-bars-arrow-up` | `lucide-arrow-up-a-z` | `phosphor-sort-ascending` | `tabler-sort-ascending` |
| `sort-desc` | Table sort descending | `heroicon-m-bars-arrow-down` | `lucide-arrow-down-z-a` | `phosphor-sort-descending` | `tabler-sort-descending` |
| `filter` | Table filter | `heroicon-m-funnel` | `lucide-filter` | `phosphor-funnel` | `tabler-filter` |
| `external-link` | External link | `heroicon-m-arrow-top-right-on-square` | `lucide-external-link` | `phosphor-arrow-square-out` | `tabler-external-link` |

### App and SaaS

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `settings` / `gear` | Settings, preferences | `heroicon-m-cog-6-tooth` | `lucide-settings` | `phosphor-gear` | `tabler-settings` |
| `dashboard` | Dashboard, overview | `heroicon-m-squares-2x2` | `lucide-layout-dashboard` | `phosphor-squares-four` | `tabler-layout-dashboard` |
| `billing` / `credit-card` | Billing, payment method | `heroicon-m-credit-card` | `lucide-credit-card` | `phosphor-credit-card` | `tabler-credit-card` |

### Infrastructure and system

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `server` | Hosting, infrastructure | `heroicon-m-server` | `lucide-server` | `phosphor-hard-drives` | `tabler-server` |
| `database` | Data store, records | `heroicon-m-circle-stack` | `lucide-database` | `phosphor-database` | `tabler-database` |
| `cloud` | Cloud service, sync | `heroicon-m-cloud` | `lucide-cloud` | `phosphor-cloud` | `tabler-cloud` |
| `shield` / `shield-check` | Security, protection | `heroicon-m-shield-check` | `lucide-shield-check` | `phosphor-shield-check` | `tabler-shield-check` |
| `inbox` | Inbox, incoming | `heroicon-m-inbox` | `lucide-inbox` | `phosphor-tray` | `tabler-inbox` |
| `bolt` | Speed, power, action | `heroicon-m-bolt` | `lucide-zap` | `phosphor-lightning` | `tabler-bolt` |
| `refresh` | Refresh, retry, sync | `heroicon-m-arrow-path` | `lucide-refresh-cw` | `phosphor-arrows-clockwise` | `tabler-refresh` |
| `undo` | Undo, revert a change | `heroicon-m-arrow-uturn-left` | `lucide-undo` | `phosphor-arrow-counter-clockwise` | `tabler-arrow-back-up` |

### Content and chrome

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `home` | Home link, breadcrumb root | `heroicon-m-home` | `lucide-home` | `phosphor-house` | `tabler-home` |
| `sign-out` | Log out | `heroicon-m-arrow-right-on-rectangle` | `lucide-log-out` | `phosphor-sign-out` | `tabler-logout` |
| `moon` | Dark theme toggle | `heroicon-m-moon` | `lucide-moon` | `phosphor-moon` | `tabler-moon` |
| `sun` | Light theme toggle | `heroicon-m-sun` | `lucide-sun` | `phosphor-sun` | `tabler-sun` |
| `system` | Theme follows the operating system — the third state beside `sun` and `moon` | `heroicon-m-computer-desktop` | `lucide-monitor` | `phosphor-monitor` | `tabler-device-desktop` |
| `code` | Code block, snippet, developer surface | `heroicon-m-code-bracket` | `lucide-code` | `phosphor-code` | `tabler-code` |
| `paint-brush` | Theming, appearance, anything a developer paints | `heroicon-m-paint-brush` | `lucide-paintbrush` | `phosphor-paint-brush` | `tabler-brush` |
| `key` | API key, credential, access | `heroicon-m-key` | `lucide-key` | `phosphor-key` | `tabler-key` |
| `rocket-launch` | Launch, ship, get started | `heroicon-m-rocket-launch` | `lucide-rocket` | `phosphor-rocket-launch` | `tabler-rocket` |
| `broadcast` | Channels, publishing, going live | `heroicon-m-radio` | `lucide-radio` | `phosphor-broadcast` | `tabler-broadcast` |
| `chart-bar` | Reporting, analytics, comparison | `heroicon-m-chart-bar` | `lucide-chart-bar` | `phosphor-chart-bar` | `tabler-chart-bar` |
| `coins` | Payments, balances, cash on hand | `heroicon-m-banknotes` | `lucide-coins` | `phosphor-coins` | `tabler-coins` |
| `gift` | Vouchers, rewards, something included | `heroicon-m-gift` | `lucide-gift` | `phosphor-gift` | `tabler-gift` |
| `list-bullets` | A plain list of items | `heroicon-m-list-bullet` | `lucide-list` | `phosphor-list-bullets` | `tabler-list` |
| `list-checks` | Tasks, checklists, things to tick off | `heroicon-m-clipboard-document-check` | `lucide-list-checks` | `phosphor-list-checks` | `tabler-list-check` |
| `lock-key` | Access, roles, permissions | `heroicon-m-lock-closed` | `lucide-lock-keyhole` | `phosphor-lock-key` | `tabler-lock` |
| `map-pin` | Locations, branches, an address | `heroicon-m-map-pin` | `lucide-map-pin` | `phosphor-map-pin` | `tabler-map-pin` |
| `percent` | Discounts, tax rates, margins | `heroicon-m-percent-badge` | `lucide-percent` | `phosphor-percent` | `tabler-percentage` |
| `sliders` | Settings, filters, fine-tuning | `heroicon-m-adjustments-horizontal` | `lucide-sliders` | `phosphor-sliders` | `tabler-adjustments` |
| `trend-up` | A metric moving up over time | `heroicon-m-arrow-trending-up` | `lucide-trending-up` | `phosphor-trend-up` | `tabler-trending-up` |
| `chart-line` | Trend over time, analytics | `heroicon-m-presentation-chart-line` | `lucide-chart-line` | `phosphor-chart-line` | `tabler-chart-line` |
| `folders` | A collection of folders, a workspace | `heroicon-m-folder` | `lucide-folders` | `phosphor-folders` | `tabler-folders` |
| `phone` | Telephone, voice call | `heroicon-m-phone` | `lucide-phone` | `phosphor-phone` | `tabler-phone` |
| `book` / `book-open` | Documentation, guide | `heroicon-m-book-open` | `lucide-book-open` | `phosphor-book-open` | `tabler-book` |
| `file-text` | Document, article | `heroicon-m-document-text` | `lucide-file-text` | `phosphor-file-text` | `tabler-file-text` |
| `copy` | Copy to clipboard | `heroicon-m-clipboard-document` | `lucide-copy` | `phosphor-copy` | `tabler-copy` |
| `globe` | Language, region, public | `heroicon-m-globe-alt` | `lucide-globe` | `phosphor-globe` | `tabler-world` |
| `map` | Location, directions | `heroicon-m-map` | `lucide-map` | `phosphor-map-trifold` | `tabler-map` |
| `lightbulb` | Tip, idea, suggestion | `heroicon-m-light-bulb` | `lucide-lightbulb` | `phosphor-lightbulb` | `tabler-bulb` |
| `megaphone` | Announcement, changelog | `heroicon-m-megaphone` | `lucide-megaphone` | `phosphor-megaphone` | `tabler-speakerphone` |

### People, time and records

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `users` | Team, members, accounts | `heroicon-m-users` | `lucide-users` | `phosphor-users` | `tabler-users` |
| `history` | Activity log, recent | `heroicon-m-clock` | `lucide-history` | `phosphor-clock-counter-clockwise` | `tabler-history` |
| `legal` | Terms, compliance | `heroicon-m-scale` | `lucide-scale` | `phosphor-scales` | `tabler-scale` |
| `badge` | Identity, credential | `heroicon-m-identification` | `lucide-badge-check` | `phosphor-identification-badge` | `tabler-badge` |
| `layers` | Grouping, versions, variants | `heroicon-m-square-3-stack-3d` | `lucide-layers` | `phosphor-stack` | `tabler-stack-2` |
| `stack` | Stacked items — the same glyph as `layers`, under the other name for it | `heroicon-m-square-3-stack-3d` | `lucide-layers` | `phosphor-stack` | `tabler-stack-2` |

### Notifications, mail and media

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `bell` | Notifications | `heroicon-m-bell` | `lucide-bell` | `phosphor-bell` | `tabler-bell` |
| `bell-slash` | Notifications muted | `heroicon-m-bell-slash` | `lucide-bell-off` | `phosphor-bell-slash` | `tabler-bell-off` |
| `message` | Conversation, comments | `heroicon-m-chat-bubble-left-right` | `lucide-message-circle` | `phosphor-chat-circle` | `tabler-message-circle` |
| `send` | Send message, submit | `heroicon-m-paper-airplane` | `lucide-send` | `phosphor-paper-plane-tilt` | `tabler-send` |
| `envelope` | Email address, mailbox | `heroicon-m-envelope` | `lucide-mail` | `phosphor-envelope` | `tabler-mail` |
| `store` | Shop, storefront, point of sale | `heroicon-m-building-storefront` | `lucide-store` | `phosphor-storefront` | `tabler-building-store` |
| `cart` | Shopping cart, basket | `heroicon-m-shopping-cart` | `lucide-shopping-cart` | `phosphor-shopping-cart` | `tabler-shopping-cart` |
| `receipt` | Receipt, proof of purchase | `heroicon-m-receipt-percent` | `lucide-receipt` | `phosphor-receipt` | `tabler-receipt` |
| `truck` | Delivery, shipment | `heroicon-m-truck` | `lucide-truck` | `phosphor-truck` | `tabler-truck` |
| `package` | Parcel, stock item | `heroicon-m-archive-box` | `lucide-package` | `phosphor-package` | `tabler-package` |
| `barcode` | Scan an article | `heroicon-m-qr-code` | `lucide-barcode` | `phosphor-barcode` | `tabler-barcode` |
| `cash-register` | The till itself, where the receipts come from | `heroicon-m-calculator` | `lucide-calculator` | `phosphor-cash-register` | `tabler-cash-register` |
| `user-add` | Invite or add a person | `heroicon-m-user-plus` | `lucide-user-plus` | `phosphor-user-plus` | `tabler-user-plus` |
| `user-remove` | Remove a person | `heroicon-m-user-minus` | `lucide-user-minus` | `phosphor-user-minus` | `tabler-user-minus` |
| `building` | Organization, tenant, site | `heroicon-m-building-office` | `lucide-building` | `phosphor-building` | `tabler-building` |
| `webhook` | Outbound callback URL | `heroicon-m-link` | `lucide-webhook` | `phosphor-webhooks-logo` | `tabler-webhook` |
| `arrow-left` | Back, previous | `heroicon-m-arrow-left` | `lucide-arrow-left` | `phosphor-arrow-left` | `tabler-arrow-left` |
| `clock` | Time, duration, history | `heroicon-m-clock` | `lucide-clock` | `phosphor-clock` | `tabler-clock` |
| `lock` | Locked, restricted | `heroicon-m-lock-closed` | `lucide-lock` | `phosphor-lock` | `tabler-lock` |
| `reply` | Reply to message | `heroicon-m-arrow-uturn-left` | `lucide-reply` | `phosphor-arrow-bend-up-left` | `tabler-arrow-back-up` |
| `forward` | Forward message | `heroicon-m-arrow-uturn-right` | `lucide-forward` | `phosphor-arrow-bend-up-right` | `tabler-arrow-forward-up` |
| `archive` | Archive, move out of inbox | `heroicon-m-archive-box` | `lucide-archive` | `phosphor-archive` | `tabler-archive` |
| `tag` | Label, category | `heroicon-m-tag` | `lucide-tag` | `phosphor-tag` | `tabler-tag` |
| `image` | Picture, media attachment | `heroicon-m-photo` | `lucide-image` | `phosphor-image` | `tabler-photo` |

### Media controls

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `play` | Start playback | `heroicon-m-play` | `lucide-play` | `phosphor-play` | `tabler-player-play` |
| `pause` | Pause playback | `heroicon-m-pause` | `lucide-pause` | `phosphor-pause` | `tabler-player-pause` |
| `stop` | Stop playback | `heroicon-m-stop` | `lucide-square` | `phosphor-stop` | `tabler-player-stop` |
| `speaker` | Audio on, volume | `heroicon-m-speaker-wave` | `lucide-volume-2` | `phosphor-speaker-high` | `tabler-volume` |
| `mute` | Audio off | `heroicon-m-speaker-x-mark` | `lucide-volume-x` | `phosphor-speaker-slash` | `tabler-volume-off` |
| `microphone` | Record, voice input | `heroicon-m-microphone` | `lucide-mic` | `phosphor-microphone` | `tabler-microphone` |

::: tip
Each preset column shows the **Blade icon identifier** — the exact string that gets passed to the `@svg()` directive. You can use these identifiers directly if you need an icon outside of WireKit's alias system; take them from the column for the preset you have configured, since the same alias resolves to a different identifier on each one.
:::

### Raw-name fallthrough

If you pass a `name` that isn't a curated alias but **does** match an icon in your active preset's library, WireKit resolves it directly to that icon and logs an informational dev hint — for example `<x-wirekit::icon name="briefcase" />` resolves to `heroicon-m-briefcase` on the default preset. This lets you reach any icon in the underlying set without registering an alias first. A name that matches neither an alias nor a real icon throws an `InvalidArgumentException` with a "did you mean" suggestion. To silence the dev hint for an icon you reach for often, register it as a [project alias](#overriding-individual-aliases).

### Using a raw icon name instead of an alias

An icon name the vocabulary does not define still resolves, if the icon package provides it:

```blade
{{-- `gear-six` is not an alias — it is Phosphor's own glyph name --}}
<x-wirekit::icon name="gear-six" />
```

**This is supported, and it couples your application to the icon package rather than to WireKit.** That trade is worth stating plainly, because the failure is delayed and lands somewhere unrelated:

- The name resolves because the full package is installed and answers it directly. The alias vocabulary is bypassed.
- Restrict that package to the icons you actually render — a reasonable thing to do, since a set can carry thousands and the manifest is built per boot — and the raw names stop resolving. One application hit exactly that: the restriction had to be reverted because four test files depended on raw names.
- Rename or reorganize glyphs upstream and the same thing happens on a package update.

A fallthrough is logged at info level in development, naming the icon and suggesting you add it to your preset. That log is the only signal you get, so it is worth reading.

**When to reach for it anyway:** a glyph the vocabulary genuinely has no concept for, or a specific variant where the alias picks a different one (`gear` resolves to Phosphor's `gear`, not `gear-six`). Both are legitimate — just know you have taken on the coupling.

**When not to:** anything the vocabulary already names. `home` rather than `house`, `legal` rather than `scales`, `history` rather than `clock-counter-clockwise`. Those hold whichever preset is configured; the raw names hold only while one particular package is fully installed.

If a concept is missing from the vocabulary — or is there under a name you would not have guessed — that is worth reporting. Several of the names above exist because somebody said so: the admin-navigation group came from an application that had reached past it for raw glyph names, and `stack` was added afterwards because that was the word it had reached for.

### Everywhere, not only on Heroicons

These words used to live in the stackable heroicons extensions, which emit heroicon
identifiers exclusively — so a Lucide, Phosphor or Tabler install could not reach them,
and stacking an extension resolved the name onto a glyph that set does not ship. Each one
below was checked against the real SVG files of all four sets before it moved here.

| Alias | Usage | Heroicons | Lucide | Phosphor | Tabler |
| --- | --- | --- | --- | --- | --- |
| `arrow-down` | Sort descending, move down, download direction | `heroicon-m-arrow-down` | `lucide-arrow-down` | `phosphor-arrow-down` | `tabler-arrow-down` |
| `arrow-right` | Forward, next step, "continue" affordance | `heroicon-m-arrow-right` | `lucide-arrow-right` | `phosphor-arrow-right` | `tabler-arrow-right` |
| `arrow-up` | Sort ascending, move up, back to top | `heroicon-m-arrow-up` | `lucide-arrow-up` | `phosphor-arrow-up` | `tabler-arrow-up` |
| `arrow-up-right` | Diagonal direction, trending up, go to | `heroicon-m-arrow-up-right` | `lucide-arrow-up-right` | `phosphor-arrow-up-right` | `tabler-arrow-up-right` |
| `chart-pie` | Share of total, composition breakdown | `heroicon-m-chart-pie` | `lucide-chart-pie` | `phosphor-chart-pie` | `tabler-chart-pie` |
| `code-bracket` | Developer surface, API reference | `heroicon-m-code-bracket` | `lucide-code` | `phosphor-code` | `tabler-code` |
| `cog-6-tooth` | Settings, configuration | `heroicon-m-cog-6-tooth` | `lucide-settings` | `phosphor-gear` | `tabler-settings` |
| `cube` | Product, module, package | `heroicon-m-cube` | `lucide-box` | `phosphor-cube` | `tabler-cube` |
| `sparkles` | Generated, enhanced, AI | `heroicon-m-sparkles` | `lucide-sparkles` | `phosphor-sparkle` | `tabler-sparkles` |
| `command-line` | CLI, terminal, shell command | `heroicon-m-command-line` | `lucide-terminal` | `phosphor-terminal` | `tabler-terminal` |
| `finger-print` | Identity, authentication, biometrics | `heroicon-m-finger-print` | `lucide-fingerprint` | `phosphor-fingerprint` | `tabler-fingerprint` |
| `fire` | Trending, hot, high activity | `heroicon-m-fire` | `lucide-flame` | `phosphor-fire` | `tabler-flame` |
| `heart` | Favorite, like, saved | `heroicon-m-heart` | `lucide-heart` | `phosphor-heart` | `tabler-heart` |
| `attach` | Attach a file, attachment | `heroicon-m-paper-clip` | `lucide-paperclip` | `phosphor-paperclip` | `tabler-paperclip` |
| `link` | Copy link, linked resource | `heroicon-m-link` | `lucide-link` | `phosphor-link` | `tabler-link` |
| `live` | Live status, streaming, real time | `heroicon-m-signal` | `lucide-radio` | `phosphor-radio` | `tabler-radio` |
| `lock-closed` | Locked, private, restricted | `heroicon-m-lock-closed` | `lucide-lock` | `phosphor-lock` | `tabler-lock` |
| `open-source` | Open source, public repository | `heroicon-m-code-bracket` | `lucide-git-branch` | `phosphor-git-branch` | `tabler-git-branch` |
| `puzzle-piece` | Plugin, integration, extension | `heroicon-m-puzzle-piece` | `lucide-puzzle` | `phosphor-puzzle-piece` | `tabler-puzzle` |
| `security` | Security posture, protection | `heroicon-m-lock-closed` | `lucide-shield` | `phosphor-shield` | `tabler-shield` |
| `speed` | Performance, fast path | `heroicon-m-bolt` | `lucide-gauge` | `phosphor-gauge` | `tabler-gauge` |
| `squares-2x2` | Grid view, dashboard layout | `heroicon-m-squares-2x2` | `lucide-grid-2x2` | `phosphor-squares-four` | `tabler-layout-grid` |
| `star` | Rating, starred, highlight | `heroicon-m-star` | `lucide-star` | `phosphor-star` | `tabler-star` |
| `swatch` | Theme, palette, colors | `heroicon-m-swatch` | `lucide-palette` | `phosphor-swatches` | `tabler-palette` |
| `unlock` | Unlocked, granted, opened | `heroicon-m-lock-open` | `lucide-unlock` | `phosphor-lock-open` | `tabler-lock-open` |
| `user-group` | Team, members, audience | `heroicon-m-user-group` | `lucide-users` | `phosphor-users` | `tabler-users` |
| `x-circle` | Error state, removed, rejected | `heroicon-m-x-circle` | `lucide-x-circle` | `phosphor-x-circle` | `tabler-circle-x` |

## Overriding Individual Aliases

Override specific aliases without changing the entire preset. This is useful when you prefer one icon from a different set:

```php
'icons' => [
    'preset' => 'heroicons',
    'aliases' => [
        'close' => 'lucide-x',  // Use Lucide's X for close only
    ],
],
```

::: info
Per-alias overrides require the corresponding Blade icon package to be installed. In the example above, both `blade-heroicons` (for the preset) and `blade-lucide-icons` (for the override) must be in your `composer.json`.
:::

Need just **one** alias from a stackable extension preset? Map it directly here instead of stacking the whole preset. For example, the `live` marketing alias lives only in `heroicons-marketing` — if it's the single alias you need, mapping it by hand is lighter than activating the full extension (and `heroicon-m-signal` ships in the `blade-heroicons` package the base preset already requires, so there's no extra install):

```php
'icons' => [
    'preset' => 'heroicons',
    'aliases' => [
        'live' => 'heroicon-m-signal',  // one marketing alias, no preset stacking
    ],
],
```

Reach for `presets` stacking (see [Available Presets](#available-presets)) only when you use *many* aliases from an extension.

`live` deliberately stays a marketing alias rather than joining the base presets: unlike `copy` / `globe` / `book` / `lightbulb` (which map to an equivalent glyph in every base library), it has no clean universal-core equivalent — `signal` / `radio` / `broadcast` differ per icon set — so the choice of glyph is left to you via the override above.

## Custom Presets

Create a class implementing `Pushery\WireKit\Contracts\IconPreset` to use any icon set:

```php
use Pushery\WireKit\Contracts\IconPreset;

class MyIconPreset implements IconPreset
{
    public function icons(): array
    {
        return [
            'close' => 'my-icon-x',
            'menu' => 'my-icon-menu',
            'search' => 'my-icon-search',
            // ... every semantic alias must be mapped
        ];
    }

    public function requires(): string
    {
        return 'vendor/my-blade-icons';  // Composer package name
    }
}
```

Then set it in config:

```php
'icons' => [
    'preset' => \App\Icons\MyIconPreset::class,
],
```

## Programmatic Usage

Resolve aliases in PHP code (useful in Livewire components or service classes):

```php
use Pushery\WireKit\WireKit;

$iconName = WireKit::icon('close'); // Returns 'heroicon-m-x-mark' (with heroicons preset)
```

## Behavior

| Scenario | Result |
| --- | --- |
| Preset configured + package installed | Icon renders as inline SVG |
| `blade-icons` not installed | `RuntimeException` with install instructions |
| Unaliased name that matches a real icon | Resolves to the underlying icon + logs an INFO dev hint (see [Raw-name fallthrough](#raw-name-fallthrough)) |
| Unknown name with no matching icon | `InvalidArgumentException` with a "did you mean" suggestion |
| Unknown preset (local) | `InvalidArgumentException` listing available presets |
| Unknown preset (production) | Exception — validate presets before deploy |

## Production

Cache icons for better performance in production:

```bash
php artisan icons:cache
```

To clear the cache (e.g. after adding new icons):

```bash
php artisan icons:clear
```

## Asking what the vocabulary knows

`WireKit::icon()` tells you what will render. It cannot tell you whether WireKit recognized the name, because it always answers: a name that is not an alias falls through to the icon set's own naming, and a real glyph name resolves that way too.

Two helpers answer the other question — useful when a tool offers completion, or when you want to check a design system's names against the ones that exist here:

```php
// 1. Is this a name WireKit DECLARES? Not "will it render" — that is icon().
WireKit::isIconAlias('webhook');   // true  — a declared alias
WireKit::isIconAlias('x-mark');    // false — renders, but only via the fallthrough
WireKit::isIconAlias('not-a-name'); // false

// 2. The whole declared vocabulary, alias => blade-icons identifier.
WireKit::iconVocabulary();          // ['close' => 'heroicon-m-x-mark', 'webhook' => …]
```

The vocabulary follows your configuration: the presets you stacked, in their precedence order, with your own `icons.aliases` last. It deliberately excludes the fallthrough — a list that contained every renderable glyph name would answer yes to everything, which is the same as answering nothing.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` | `null` | Semantic icon alias (e.g. `'close'`, `'search'`, `'trash'`) |
| `size` | `string\|null` | `null` | Icon size: `xs` (12px), `sm` (16px), `md` (20px), `lg` (24px), `xl` (32px). When `null`, defaults to `h-5 w-5` (20px). |

All other attributes are passed through to the underlying SVG element (e.g. `class`, `aria-hidden`).

### Sizing

The `size` prop sets the icon's width and height to a token-aligned size class. When `size` is `null` (default), the historical `h-5 w-5` (20px) class is applied — back-compat is preserved for every existing call site.

```blade
<x-wirekit::icon name="search" size="xs" />  {{-- h-3 w-3 → 12px --}}
<x-wirekit::icon name="search" size="sm" />  {{-- h-4 w-4 → 16px --}}
<x-wirekit::icon name="search" size="md" />  {{-- h-5 w-5 → 20px (same as default) --}}
<x-wirekit::icon name="search" size="lg" />  {{-- h-6 w-6 → 24px --}}
<x-wirekit::icon name="search" size="xl" />  {{-- h-8 w-8 → 32px --}}
```

> `search` is in the default `heroicons` preset; if you want `cursor-arrow-rays` / `pulse` and other marketing-flavored aliases, opt into the extension preset via `wirekit.icons.presets => ['heroicons', 'heroicons-marketing']`. Run `php artisan wirekit:icons --preset=heroicons-marketing` to see the full alias list.

Passing an invalid size triggers `WireKit::validateProp()` — throws `InvalidArgumentException` in debug, falls back to `xs` and logs a warning in production. To override the size with a custom Tailwind class, omit the `size` prop and pass `class="h-10 w-10"` directly.

## Accessibility

Icons are either **decorative** (purely visual, meaning conveyed by adjacent text) or **informative** (they carry meaning on their own). WireKit defaults to decorative because the vast majority of icons in a UI accompany a text label.

### Decorative Icons (Default)

An icon next to a text label is decorative. Screen readers should skip it to avoid duplicate announcements. WireKit **automatically** adds `aria-hidden="true"` in this case — you don't have to do anything.

```blade
<!-- "Delete" is already announced — icon is skipped by screen readers -->
<x-wirekit::button>
    <x-wirekit::icon name="trash" />
    Delete
</x-wirekit::button>
```

Rendered output:

```html
<svg aria-hidden="true" class="h-5 w-5" ...></svg>
```

### Informative Icons (Icon-Only Buttons)

When an icon stands alone (no visible text), it becomes the accessible name. Pass `aria-label` — WireKit detects this and will **not** add `aria-hidden`, so the icon is exposed to assistive tech.

```blade
<!-- Icon-only close button: icon itself carries the label -->
<button type="button" aria-label="Close dialog">
    <x-wirekit::icon name="close" />
</button>
```

A second, widely-used pattern is the `sr-only` text node inside the button — this leaves the `<svg>` decorative while giving the button an accessible name:

```blade
<button type="button">
    <x-wirekit::icon name="close" />
    <span class="sr-only">Close dialog</span>
</button>
```

Both approaches are valid. The `sr-only` pattern keeps the icon purely decorative (cleaner SVG output) and is slightly more robust against future label changes.

### Informative Icons Inside Text

If an icon communicates something independently of nearby text (e.g. a status indicator), set `role="img"` + `aria-label`:

```blade
<span>
    Order status:
    <x-wirekit::icon name="success" role="img" aria-label="completed" />
</span>
```

WireKit detects `role="img"` and omits the automatic `aria-hidden`.

### Detection Rules

WireKit decides automatically based on the attributes you pass:

| Attribute you pass | WireKit adds `aria-hidden="true"`? |
| --- | --- |
| None (default) | Yes — decorative |
| `aria-label="..."` | No — informative |
| `aria-labelledby="..."` | No — informative |
| `role="img"` | No — informative |
| `aria-hidden="true"` (explicit) | Respected — your value wins |
| `aria-hidden="false"` (explicit) | Respected — forces exposure |

### Further Reading

- [WAI-ARIA Authoring Practices — Image Role](https://www.w3.org/WAI/ARIA/apg/patterns/img/)
- [WebAIM: Alternative Text](https://webaim.org/techniques/alttext/)
- [MDN: `aria-hidden`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden)

## Keyboard Interaction

This component is purely presentational and does not respond to keyboard input.

## Pitfalls

- **Don't ship `<x-wirekit::icon>` without an `aria-label` if it carries meaning.** Icons are `aria-hidden="true"` by default — perfect for decorative flourishes, wrong for icon-only buttons. Set `aria-label` on the surrounding button instead.
- **Don't use `class="h-N w-N"` to size icons.** Use the `size="xs|sm|md|lg|xl"` prop instead — it ensures the size is token-driven and consistent across the project.

## Design Tokens

The icon component renders raw `<svg>` markup with `currentColor` so color follows the surrounding text token. Sizing uses Tailwind utility classes (`h-4 w-4`, etc.) rather than design tokens, mirroring the rest of WireKit's icon usage. The icon doesn't reach for tokens directly — its color and size come from whichever component or context renders it.

| Source | Used for |
| --- | --- |
| `currentColor` (CSS keyword) | SVG fill / stroke — inherits from parent `color` (any `--color-wk-text` / `--color-wk-accent` / `--color-wk-danger` etc. set on the parent) |
| Tailwind `h-* w-*` | Width + height (structural, not themed) |
