# Icons

Lets readers browse a set of icons by name and copy the SVG of each one.

### Known issues
None known.

### Copy the markup
Icon grid markup
```html
<ul class="luz-icon-grid">
  <li class="luz-icon-item">
    <span class="luz-icon-display"><svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14"/></svg></span>
    <span class="luz-icon-name" id="icon-plus">Plus</span>
    <button class="luz-copy-btn" type="button" id="icon-plus-copy" aria-labelledby="icon-plus-copy icon-plus" data-copy="&lt;svg …&gt;…&lt;/svg&gt;">Copy SVG</button>
  </li>
</ul>
```

The same icons as a sprite: paste it once in the page, then draw each one with `<use>`. The sprite works only in the same document (`href="#id"`); a `<use>` that points at a file on another origin, a CDN included, is blocked by browsers.

Icon sprite markup
```html
<svg width="0" height="0" aria-hidden="true" focusable="false">
  <symbol id="luz-icon-menu" viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></symbol>
  <symbol id="luz-icon-close" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18"/></symbol>
  <!-- …the rest of the set, one symbol each -->
</svg>

<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><use href="#luz-icon-cart"/></svg>
```

An icon beside a label, and an icon alone. A button names itself from its text, so give an icon-only button a name in a `.u-sr-only` span, not an `aria-label`: the span is translated with the page.

Icon in a button markup
```html
<!-- With a label: the icon is 16 px inside a button -->
<button class="luz-btn luz-btn--primary" type="submit">
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 4h2.5l2.2 10.5h9.6L19.5 7H6.2"/><circle cx="9" cy="19" r="1.4"/><circle cx="17" cy="19" r="1.4"/></svg>
  Add to cart
</button>

<!-- Icon only: the name is real text, hidden from the eye -->
<button class="luz-btn luz-btn--ghost" type="button">
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
  <span class="u-sr-only">Menu</span>
</button>
```

Two icons point to the end of the line: `chevron-end` and `arrow-end`, marked with `data-luz-flip`. In right-to-left text, LUZ mirrors anything with that attribute using the rule below, in core's utilities layer, so you write nothing.

Add the attribute to an icon of your own that points to the end of the line.

Right-to-left rule, shipped in luz.utilities
```css
:where([data-luz-flip]):dir(rtl) {
  transform: scaleX(-1);
}
```

### Variants and options
There are no modifiers. The grid fits as many columns of at least 100 px as the width allows.

- `.luz-icon-grid`: The list: a grid with no bullets
- `.luz-icon-item`: One bordered cell: icon, name, copy button
- `.luz-icon-display`: A 48 × 48 px box that centres the icon, in the secondary text colour
- `.luz-icon-name`: The name under the icon

### How it works
A `<ul>` of icons, styled by `components/icon-grid.css`. The copy buttons are [copy buttons](https://nandovejer.github.io/luz/docs/components/copy-button/), wired by `clipboard.js`.

- Each button carries the icon's SVG, escaped, in `data-copy`. On this page a script fills it from the icon beside the button, so the page does not carry every icon twice.
- The icons are LUZ's own, drawn for it on a 24 × 24 grid with a 1.5 px round stroke in `currentColor`. They are not a package and no file is loaded: copy the SVG, or the sprite, into your page.
- An icon is 24 × 24 px as written, and 16 px inside a `.luz-btn`. For an icon that must follow the text size, set `width="1.5em" height="1.5em"`.

### Without JavaScript
The copy buttons are hidden. The grid still shows every icon and its name.

### Keyboard and ARIA
Tab reaches each copy button; Enter or Space copies the SVG.

- Each button is named by its own text and the icon's name, with `aria-labelledby`: "Copy SVG Plus".
- The icons are `aria-hidden="true"` and `focusable="false"`: the name is the text under them, or the `.u-sr-only` text of the button that holds them.
- Info and warning always come with words. A lone glyph says nothing to someone who cannot see its shape or its colour: put the words beside it, or give a stand-alone icon `role="img"` and a name.
- The result of each copy is announced in a polite live region.

### When to use
Use an icon grid to let readers browse a set of icons and copy the one they need.

### When not to use
Do not use it to lay out icons that do something: it is a catalogue, not a toolbar.

- For a row of actions, use buttons with text in an [action group](https://nandovejer.github.io/luz/docs/components/layout/#objects-actions).
- Never use an icon as the only label of an action: give it its name as text, visible or in a `.u-sr-only` span.
- For a logo or an illustration, use an `<img>` or an SVG at its own size.
- For hundreds of icons, bring your own set.
