# Icon (/docs/components/visuals/icon)



`Icon` renders a symbol from the Luke UI spritesheet. It requires an `IconSpritesheetProvider`
ancestor. See Setup below.

<ExampleBlock src="icon/basic" title="Icon — Basic" description="Standalone and decorative icons from the spritesheet." />

## Best practices [#best-practices]

| Guidance | Practices                                                                                                 |
| -------- | --------------------------------------------------------------------------------------------------------- |
| Do       | Pass `title` when the icon conveys meaning without adjacent text, such as a standalone status icon.       |
| Don't    | Pass both `aria-hidden` and `title`. A titled icon should be exposed to assistive technology, not hidden. |

## Setup [#setup]

Wrap your app with `IconSpritesheetProvider`.

* Source asset: `@luke-ui/react/spritesheet.svg`, exported from `./dist/spritesheet.svg`
* Runtime lookup: `<configured-sprite-href>#<icon-name>`

```tsx
<IconSpritesheetProvider href="/assets/spritesheet.svg">
	<App />
</IconSpritesheetProvider>
```

Vite and Storybook should import the spritesheet as a URL.

```ts
import spriteSheetHref from '@luke-ui/react/spritesheet.svg?url&no-inline';

<IconSpritesheetProvider href={spriteSheetHref}>
	<App />
</IconSpritesheetProvider>;
```

The `no-inline` query avoids `data:` URLs, which can break `<use href="...#icon-id">` rendering.

When developing `@luke-ui/react`, generate icons from `packages/@luke-ui/react/icons/*.svg` into
`packages/@luke-ui/react/dist/spritesheet.svg`.

```bash
pnpm --dir packages/@luke-ui/react run generate:icons
```

## How it works [#how-it-works]

`Icon` renders an `<svg>` that references a symbol in the generated spritesheet with
`<use href="..." />`.

* `name` chooses the symbol id.
* The sprite URL comes from `IconSpritesheetProvider`.
* `viewBox` defaults to the generated icon viewBox.
* Icon fill follows `currentColor`.

```tsx
<Icon name="add" className="myIcon" style={{ color: 'tomato' }} />
```

## Create your own icon [#create-your-own-icon]

Use `createIcon` for a one-off icon that is not in the generated spritesheet.

<ExampleBlock src="icon/custom" title="Icon — Custom" description="Create a one-off icon that is not in the generated spritesheet." />

## Accessibility [#accessibility]

If `title` is provided, the icon is exposed to assistive technology with `role="img"`. If `title` is
omitted, `aria-hidden` defaults to `true`.

## Props [#props]

<TypeTable
  id="type-table-index.tsx-IconProps"
  type="{
  &#x22;id&#x22;: &#x22;index.tsx-IconProps&#x22;,
  &#x22;name&#x22;: &#x22;IconProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for the built-in `Icon` component.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;id&#x22;,
      &#x22;description&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;style&#x22;,
      &#x22;description&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;React.CSSProperties | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;object&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;className&#x22;,
      &#x22;description&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;aria-hidden&#x22;,
      &#x22;description&#x22;: &#x22;Indicates whether the element is exposed to an accessibility API.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;see&#x22;,
          &#x22;text&#x22;: &#x22;aria-disabled.&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;Booleanish | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;viewBox&#x22;,
      &#x22;description&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;size&#x22;,
      &#x22;description&#x22;: &#x22;Sets the icon size.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'medium'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;medium\&#x22; | \&#x22;small\&#x22; | \&#x22;xsmall\&#x22; | \&#x22;large\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;name&#x22;,
      &#x22;description&#x22;: &#x22;Icon name from the generated icon set.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;reset\&#x22; | \&#x22;theme\&#x22; | \&#x22;filter\&#x22; | \&#x22;fontFamily\&#x22; | \&#x22;position\&#x22; | \&#x22;help\&#x22; | \&#x22;search\&#x22; | \&#x22;link\&#x22; | \&#x22;add\&#x22; | \&#x22;layout\&#x22; | \&#x22;hide\&#x22; | \&#x22;menu\&#x22; | \&#x22;shift\&#x22; | \&#x22;send\&#x22; | \&#x22;informative\&#x22; | \&#x22;caution\&#x22; | \&#x22;critical\&#x22; | \&#x22;addCircle\&#x22; | \&#x22;addUser\&#x22; | \&#x22;addWidget\&#x22; | \&#x22;administration\&#x22; | \&#x22;analytics\&#x22; | \&#x22;arrowBottom\&#x22; | \&#x22;arrowDown\&#x22; | \&#x22;arrowLeft\&#x22; | \&#x22;arrowRight\&#x22; | \&#x22;arrowSplit\&#x22; | \&#x22;arrowTop\&#x22; | \&#x22;arrowUp\&#x22; | \&#x22;attachment\&#x22; | \&#x22;barChartHorizontal\&#x22; | \&#x22;barChartVertical\&#x22; | \&#x22;benefits\&#x22; | \&#x22;bolt\&#x22; | \&#x22;bookmark\&#x22; | \&#x22;bookmarkFilled\&#x22; | \&#x22;bulb\&#x22; | \&#x22;bulkImport\&#x22; | \&#x22;calendar\&#x22; | \&#x22;careers\&#x22; | \&#x22;category\&#x22; | \&#x22;changePassword\&#x22; | \&#x22;chat\&#x22; | \&#x22;check\&#x22; | \&#x22;checkCircle\&#x22; | \&#x22;checklist\&#x22; | \&#x22;chevronDown\&#x22; | \&#x22;chevronLeft\&#x22; | \&#x22;chevronRight\&#x22; | \&#x22;chevronUp\&#x22; | \&#x22;clap\&#x22; | \&#x22;clipboard\&#x22; | \&#x22;clock\&#x22; | \&#x22;close\&#x22; | \&#x22;closeCircle\&#x22; | \&#x22;codeBlock\&#x22; | \&#x22;comment\&#x22; | \&#x22;competency\&#x22; | \&#x22;connect\&#x22; | \&#x22;contracts\&#x22; | \&#x22;contribute\&#x22; | \&#x22;copyIcon\&#x22; | \&#x22;courseBuilder\&#x22; | \&#x22;covidSecure\&#x22; | \&#x22;customReport\&#x22; | \&#x22;dashboard\&#x22; | \&#x22;dataImport\&#x22; | \&#x22;databaseOff\&#x22; | \&#x22;deactivatedUser\&#x22; | \&#x22;delete\&#x22; | \&#x22;delimiter\&#x22; | \&#x22;department\&#x22; | \&#x22;design\&#x22; | \&#x22;dislike\&#x22; | \&#x22;document\&#x22; | \&#x22;documents\&#x22; | \&#x22;download\&#x22; | \&#x22;dragHandle\&#x22; | \&#x22;eLMOAssist\&#x22; | \&#x22;edit\&#x22; | \&#x22;editChart\&#x22; | \&#x22;elmo\&#x22; | \&#x22;event\&#x22; | \&#x22;expand\&#x22; | \&#x22;expenses\&#x22; | \&#x22;experience\&#x22; | \&#x22;export\&#x22; | \&#x22;externalLink\&#x22; | \&#x22;favorite\&#x22; | \&#x22;favoriteFilled\&#x22; | \&#x22;feedback\&#x22; | \&#x22;firstPage\&#x22; | \&#x22;flag\&#x22; | \&#x22;folder\&#x22; | \&#x22;github\&#x22; | \&#x22;gridView\&#x22; | \&#x22;home\&#x22; | \&#x22;hybridWork\&#x22; | \&#x22;indeterminate\&#x22; | \&#x22;insights\&#x22; | \&#x22;interview\&#x22; | \&#x22;lastPage\&#x22; | \&#x22;learning\&#x22; | \&#x22;leave\&#x22; | \&#x22;lightMode\&#x22; | \&#x22;like\&#x22; | \&#x22;lineChart\&#x22; | \&#x22;location\&#x22; | \&#x22;lock\&#x22; | \&#x22;mail\&#x22; | \&#x22;mobilePhone\&#x22; | \&#x22;myTeam\&#x22; | \&#x22;overflowHorizontal\&#x22; | \&#x22;overflowVertical\&#x22; | \&#x22;path\&#x22; | \&#x22;payroll\&#x22; | \&#x22;pdf\&#x22; | \&#x22;performance\&#x22; | \&#x22;phone\&#x22; | \&#x22;picture\&#x22; | \&#x22;pieChart\&#x22; | \&#x22;pin\&#x22; | \&#x22;play\&#x22; | \&#x22;preferences\&#x22; | \&#x22;profile\&#x22; | \&#x22;quiz\&#x22; | \&#x22;readinessScore\&#x22; | \&#x22;rearrange\&#x22; | \&#x22;recruitment\&#x22; | \&#x22;redo\&#x22; | \&#x22;remuneration\&#x22; | \&#x22;reports\&#x22; | \&#x22;restore\&#x22; | \&#x22;rostering\&#x22; | \&#x22;sSO\&#x22; | \&#x22;save\&#x22; | \&#x22;saveAs\&#x22; | \&#x22;secure\&#x22; | \&#x22;selectInput\&#x22; | \&#x22;setup\&#x22; | \&#x22;share\&#x22; | \&#x22;signout\&#x22; | \&#x22;sortBy\&#x22; | \&#x22;sortList\&#x22; | \&#x22;star\&#x22; | \&#x22;starFilled\&#x22; | \&#x22;succession\&#x22; | \&#x22;summary\&#x22; | \&#x22;survey\&#x22; | \&#x22;switchAccount\&#x22; | \&#x22;sync\&#x22; | \&#x22;target\&#x22; | \&#x22;task\&#x22; | \&#x22;test\&#x22; | \&#x22;textfieldInput\&#x22; | \&#x22;treeView\&#x22; | \&#x22;twoColumn\&#x22; | \&#x22;undo\&#x22; | \&#x22;unlink\&#x22; | \&#x22;upload\&#x22; | \&#x22;userFilled\&#x22; | \&#x22;verticalStack\&#x22; | \&#x22;view\&#x22; | \&#x22;viewLock\&#x22; | \&#x22;wave\&#x22; | \&#x22;work\&#x22;&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: true,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;title&#x22;,
      &#x22;description&#x22;: &#x22;Accessible label. When set, the icon is announced as an image.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    }
  ]
}"
/>
