> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mzizi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Icons

> Icon conventions in the Mzizi design system — where icons are imported from, the size scale, and accessible icon-only controls.

The design system's icon library is **Lucide**. It is also one of the three declared fork
seams on the `swappable` strand, which changes how you import from it.

## Import through the registry's icon module

```tsx theme={null}
import { Sun, ArrowRight } from "@/lib/icons"
```

`lib/icons` re-exports the icon library. Importing through it rather than reaching for
`lucide-react` directly is the whole mechanism by which an adopter can swap the icon library
and inherit everything else unchanged — an import scattered across two hundred components is
not a seam.

Import specific icons, never the whole library, so tree-shaking works.

## Sizing

| Context | Class | Pixels | Usage |
| - | - | - | - |
| Inline text | `size-3` | 12px | Inside badges, small labels |
| Button icon | `size-4` | 16px | Icon buttons, button with text |
| Card icon | `size-5` | 20px | Card headers, list items |
| Feature icon | `size-6` | 24px | Feature cards, section icons |
| Hero icon | `size-8` | 32px | Large display icons |
| Illustration | `size-12` | 48px | Empty states, large callouts |

Use the `size-*` shorthand, which sets width and height together, rather than separate `h-*`
and `w-*` classes that can drift apart.

## Common icons

### Navigation

| Icon | Usage |
| - | - |
| `Menu` | Mobile menu toggle |
| `X` | Close, dismiss |
| `ArrowLeft` / `ArrowRight` | Back, next |
| `ChevronDown` | Dropdown trigger |
| `ExternalLink` | External links |

### Actions

| Icon | Usage |
| - | - |
| `Search` | Search input |
| `Plus` | Create |
| `Trash2` | Delete |
| `Pencil` | Edit |
| `Copy` | Copy to clipboard |
| `Share2` | Share |
| `Download` | Download |

### Status

| Icon | Usage |
| - | - |
| `Check` | Completion, validation passed |
| `AlertCircle` | Warning |
| `AlertTriangle` | Error |
| `Info` | Informational |
| `Loader2` | Loading spinner, with `animate-spin` |

## Accessibility

### Icon-only controls

An icon without visible text needs an accessible name:

```tsx theme={null}
{/* aria-label */}
<Button variant="ghost" size="icon" aria-label="Close dialog">
  <X className="size-4" />
</Button>

{/* or visually hidden text */}
<Button variant="ghost" size="icon">
  <Search className="size-4" />
  <span className="sr-only">Search</span>
</Button>
```

Remember the 48px minimum touch target applies to icon buttons too — the icon is 16px, the
control is not.

### Decorative icons

An icon beside visible text is decorative and should be hidden from assistive technology:

```tsx theme={null}
<Button>
  <Plus className="size-4" aria-hidden="true" />
  Add item
</Button>
```

Lucide icons set `aria-hidden="true"` by default, so this is usually handled for you.

## Colour

Icons inherit colour through `currentColor`. Use text colour utilities and semantic tokens:

```tsx theme={null}
<Search className="size-4 text-muted-foreground" />
<Check className="size-4 text-[var(--status-success)]" />
```

Prefer the semantic token to the mineral — `--status-success` rather than `--color-malachite`
— so the icon follows the theme rather than pinning a colour.

## Right-to-left

Mark directional icons that should flip in RTL contexts:

```tsx theme={null}
<ArrowRight className="size-4" data-rtl-mirror="true" />
```

A chevron that points at the next item should mirror; a logo should not.

## Pairing icons with text

```tsx theme={null}
<span className="flex items-center gap-1.5 text-sm text-muted-foreground">
  <Clock className="size-3.5" />
  3 minutes ago
</span>

<Button className="gap-2">
  <Download className="size-4" />
  Download report
</Button>
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.