# Icon

The wrapper every Glint glyph goes through, giving a Lucide icon one size, tint and stroke width.

```slint
import { Icon } from "@glint/components/icon.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Icon { icon: IconSet.Heart; size: 24px; tint: Tokens.color-destructive; }
            Icon { icon: IconSet.Star; size: 24px; tint: Tokens.color-warning; }
            Icon { icon: IconSet.CheckCircle2; size: 24px; tint: Tokens.color-affirm; }
            Icon { icon: IconSet.Zap; size: 24px; tint: Tokens.color-primary; }
        }
    }
}
```

## Usage

```slint
import { Icon } from "@glint/components/icon.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component AppWindow inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;

            Icon {
                icon: IconSet.Sliders;
                size: 20px;
                tint: Tokens.color-foreground;
            }
        }
    }
}
```

`Icon` is a wrapper around `lucide-slint`’s `IconDisplay`. It standardizes properties with token support for `size`, `tint`, and `stroke-width`.

Note that `@lucide` is an external peer dependency provided by `lucide-slint` that the consumer includes in their Slint environment, not something Glint vendors directly.

## Examples

### Sizes and stroke widths

Icons scale to custom pixel dimensions and adjust their line weight with `stroke-width`.

```slint
import { Icon } from "@glint/components/icon.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Icon {
                icon: IconSet.Settings;
                size: 16px;
            }

            Icon {
                icon: IconSet.Settings;
                size: 24px;
                stroke-width: 1.5px;
            }

            Icon {
                icon: IconSet.Settings;
                size: 32px;
                stroke-width: 2.5px;
            }
        }
    }
}
```

### Tint colors

Use semantic color tokens to tint icon paths.

```slint
import { Icon } from "@glint/components/icon.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Icon {
                icon: IconSet.Flame;
                size: 24px;
                tint: Tokens.color-destructive;
            }

            Icon {
                icon: IconSet.ShieldCheck;
                size: 24px;
                tint: Tokens.color-affirm;
            }

            Icon {
                icon: IconSet.Sparkles;
                size: 24px;
                tint: Tokens.color-primary;
            }
        }
    }
}
```

## API Reference

### Properties

| Property       | Type            | Default                   | Description                                           |
| -------------- | --------------- | ------------------------- | ----------------------------------------------------- |
| `icon`         | `in LucideIcon` | no default                | Icon selected from lucide-slint's IconSet.            |
| `size`         | `in length`     | `16px`                    | Pixel side length of the square icon.                 |
| `tint`         | `in color`      | `Tokens.color-foreground` | Stroke color; defaults to the Relay foreground token. |
| `stroke-width` | `in length`     | `2px`                     | Stroke thickness used by the Lucide renderer.         |

## Accessibility

- **An icon says nothing on its own.** `Icon` declares no `accessible-role` and no label — it is strokes in a box. A glyph beside a word is exactly right that way: the word is what is announced, and a second announcement of the same thing is noise.
- **A glyph that is the only label needs one.** An icon-only control carries its name on the control, not on the icon: `Button { accessible-label: "Delete"; }` around an `IconSet.Trash`. Glint’s own icon-only controls already do this and take the name from a property — Dialog’s X from `close-label`, the carousel’s steps from `previous-label` / `next-label`.
- **Silence it where its host already speaks.** An icon inside a component that publishes its own label can still be reached by a tree walker; Glint marks those `accessible-role: none` — the badge’s glyph, the bullet in a `BulletList`, the required asterisk on a `Label` — and a call site composing its own row should do the same.
- **Tint is not a message.** `tint` changes no announcement, so an icon whose color is the state — a red error glyph — needs that state in words on the control or in its accessible description.
