# Icon

> A Lucide icon by name, from a small fixed set, sized at 14, 16, or 20px and colored by the text color.

- Name: `icon`
- Status: beta
- Categories: media, display
- File: the install writes `icon.tsx` to your `ui` alias, `@/components/ui` by default.
- npm packages: `lucide-react`. The install adds them.
- Gallery: https://arbokui.com/components/icon
- Registry item: https://arbokui.com/r/icon.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/icon
   ```

## Use it for

- Drawing an icon from data, like a name stored with a menu item or a list row.
- Use size sm in compact rows, md by default, and lg in hub rows.
- Set the color with a text token class, like text-muted-foreground or text-primary.
- Pass title when the icon stands alone and means something. Leave it off when text beside it says the same thing.

## Avoid it for

- Icons you write in code. Import them from lucide-react, like \<Calendar />. Other parts take icons as elements.
- Names outside the set. They draw an empty box and warn once. Import that icon from lucide-react instead.
- Content spots, like a feature list, an empty state, or a card's header. Use SpotIcon.
- Raw colors. Use a text token class, so the icon follows the theme.

## Props

- `name`: `IconName`. A kebab-case Lucide name from the set: arrow-right, bell, calendar, camera, check, chevron-down, chevron-right, circle-alert, clock, credit-card, download, external-link, eye, file-text, flag, heart, house, image, info, link, lock, mail, map-pin, medal, megaphone, message-circle, minus, pencil, phone, plus, search, settings, share, shield, shirt, star, ticket, trash-2, triangle-alert, trophy, upload, user, users, x. iconNames lists them.
- `size`: `"sm" | "md" | "lg"`. Default `"md"`. sm is 14px, md is 16px, lg is 20px.
- `strokeWidth`: `number`. Default `2`. Line width. lg draws 1.75 unless you set it.
- `title`: `string`. Names the icon for screen readers. Without it the icon is hidden from them.
- `className`: `string`. Extra classes. Set the color here, like text-muted-foreground. Later classes win.

## Accessibility

- Without title the icon has aria-hidden, so text beside it is all a screen reader hears.
- With title it is role="img" with that name. Use it only when the icon stands alone.
- An icon inside a button does not name the button. Give an icon-only button its own aria-label.
- It takes the text color, so a text token's contrast covers it.

## Examples

### An icon beside text

```tsx
<p className="flex items-center gap-1.5 text-muted-foreground">
  <Icon name="calendar" />
  Tuesday 6 October
</p>
```

### Sizes

```tsx
<div className="flex items-center gap-3">
  <Icon name="bell" size="sm" />
  <Icon name="bell" />
  <Icon name="bell" size="lg" />
</div>
```

### An icon from data, with a name

```tsx
const status = { icon: "triangle-alert", label: "Sign-in errors" } as const;

<Icon name={status.icon} title={status.label} className="text-muted-foreground" />
```
