# Iconography

Icons from the Tempo catalog, and how to size, color, and label them.

## Overview

`@tempoxyz/ds/icons` exports the 303 icons on the Platform Icons Figma page as React components. Each draws a 16 by 16 grid at `1em` square and fills with `currentColor`, so an icon takes the size and color of the text around it.

```tsx
import {
  AddFunds,
  AlertTriangle,
  CheckCircle,
  Copy,
  ExternalLink,
  InfoCircle,
  Key,
  QRCode,
  Search,
  Send,
  Settings,
  Wallet,
} from '@tempoxyz/ds/icons'
import { style } from '@tempoxyz/ds'

export const fill = true
const icons = [
  ['Send', Send],
  ['AddFunds', AddFunds],
  ['Wallet', Wallet],
  ['QRCode', QRCode],
  ['Copy', Copy],
  ['ExternalLink', ExternalLink],
  ['Key', Key],
  ['Settings', Settings],
  ['Search', Search],
  ['InfoCircle', InfoCircle],
  ['AlertTriangle', AlertTriangle],
  ['CheckCircle', CheckCircle],
] as const

export function Demo() {
  return (
    <ul {...styles.grid()}>
      {icons.map(([label, Icon]) => (
        <li key={label} {...styles.item()}>
          <Icon {...styles.icon()} />
          <code {...styles.label()}>{label}</code>
        </li>
      ))}
    </ul>
  )
}

namespace styles {
  export const grid = style({
    display: 'grid',
    gap: '2',
    gridTemplateColumns: 'repeat(auto-fill, minmax(6.5rem, 1fr)) !custom',
    listStyle: 'none',
    margin: '0',
    padding: '0',
  })

  export const icon = style({ fontSize: '2xl' })

  export const item = style({
    alignItems: 'center',
    backgroundColor: 'grayAlpha.100',
    borderRadius: '2xl',
    color: 'foreground',
    display: 'grid',
    gap: '2',
    justifyItems: 'center',
    paddingBlock: '4',
    paddingInline: '2',
  })

  export const label = style({ color: 'gray.900', typography: 'label.12.mono' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Foundations/Icons.tsx)

Import icons one at a time. Each is its own module, so a build carries only the icons it uses, and none needs a stylesheet or plugin.

```tsx
import { Copy, Send } from '@tempoxyz/ds/icons'
```

## Catalog

Names follow Figma in PascalCase, such as `ArrowUpRight` and `QRCode`. `InfinityIcon` avoids the JavaScript global `Infinity`.

| Group                | Examples                                                                                              |
| -------------------- | ----------------------------------------------------------------------------------------------------- |
| Money and payments   | `Send`, `AddFunds`, `Wallet`, `Bank`, `CreditCard`, `Invoice`, `Receipt`, `GasFee`                    |
| Onchain              | `CryptoToken`, `CryptoNetwork`, `TokenStack`, `Ethereum`, `Bitcoin`, `Key`, `Passkey`, `SecretPhrase` |
| Status               | `InfoCircle`, `CheckCircle`, `AlertTriangle`, `AlertCircle`, `XCircle`, `Pending`                     |
| Actions              | `Copy`, `Edit`, `Delete`, `Plus`, `Search`, `Filter`, `Share`, `Download`, `Refresh`                  |
| Navigation           | `ChevronDown`, `ChevronRight`, `ArrowLeft`, `ExternalLink`, `Home`, `MoreHorizontal`                  |
| Data and performance | `Analytics`, `ChartBar`, `CandlestickChart`, `Trend`, `Gauge`, `Lightning`, `Timer`, `Server`         |

Some icons share a name with a component, such as `Calendar`, `Gauge`, `Menu`, `Table`, and `Tag`. Rename them on import.

```tsx
import { Table } from '@tempoxyz/ds'
import { Table as TableIcon } from '@tempoxyz/ds/icons'
```

Raw SVGs keep the original Figma export for use outside React. Import them through your bundler's asset support, such as `@tempoxyz/ds/icons/Copy.svg`.

## Sizing and Color

An icon inherits `font-size` and `color`. Inside a `Button`, it follows the label's 12, 14, or 16px type and its text color, so you add the icon as a child and nothing else.

```tsx
import { Button, style, Tooltip } from '@tempoxyz/ds'
import { CheckCircle, Copy, Plus, Send } from '@tempoxyz/ds/icons'

export function Demo() {
  return (
    <div {...styles.stack()}>
      <span {...styles.small()}>
        <Copy />
        Copy address
      </span>
      <span {...styles.medium()}>
        <Send />
        Send payment
      </span>
      <span {...styles.positive()}>
        <CheckCircle />
        Payment confirmed
      </span>
      <div {...styles.row()}>
        <Button>
          <Plus />
          Add funds
        </Button>
        <Tooltip.Provider>
          <Tooltip.Root>
            <Tooltip.Trigger
              render={<Button aria-label="Copy address" shape="icon" variant="secondary" />}
            >
              <Copy />
            </Tooltip.Trigger>
            <Tooltip.Popup>Copy address</Tooltip.Popup>
          </Tooltip.Root>
        </Tooltip.Provider>
      </div>
    </div>
  )
}

namespace styles {
  export const medium = style({
    alignItems: 'center',
    color: 'foreground',
    display: 'inline-flex',
    gap: '2',
    typography: 'copy.16',
  })

  export const positive = style({
    alignItems: 'center',
    color: 'green.900',
    display: 'inline-flex',
    gap: '2',
    typography: 'label.14.strong',
  })

  export const row = style({ alignItems: 'center', display: 'flex', gap: '3' })

  export const small = style({
    alignItems: 'center',
    color: 'gray.900',
    display: 'inline-flex',
    gap: '1',
    typography: 'copy.13',
  })

  export const stack = style({ display: 'grid', gap: '4', justifyItems: 'start' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Foundations/IconSizing.tsx)

Size a standalone icon with a `fontSize` token on the icon or its parent, rather than `width` and `height`.

| Context                      | Size                  | Example                                 |
| ---------------------------- | --------------------- | --------------------------------------- |
| Inline with text             | `1em`, the default    | An icon in a button or a link           |
| Status icon beside a message | `xl` (20px)           | `Toast` icons                           |
| Callout icons                | `sm`, `base`, or `xl` | `small`, `medium`, and `large` callouts |
| Feature or list icons        | `xl` in an `IconChip` | The lead icon of a settings row         |

Color an icon through `color` on the icon or its parent, with the same tokens as text: `foreground`, `gray.900`, or an intent step such as `green.900`. Status icons in `Toast` use step 700, or `red.800` for `negative`.

## Meanings

Components already use these icons for these jobs. Use the same icon for the same meaning across a product, and don't give one icon two meanings.

| Meaning                                | Icon                                                        | Used by                                                     |
| -------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- |
| Dismiss or clear                       | `Close`                                                     | `Dialog`, `Drawer`, `Toast`, `Banner`, `Input`              |
| Open a list or expand                  | `ChevronDown`                                               | `Select`, `Combobox`, `Accordion`, `SplitButton`            |
| Go deeper or forward                   | `ChevronRight`                                              | `Breadcrumbs`, `Menu` submenus, `SidebarMenu`, `Pagination` |
| Selected                               | `Check`                                                     | `Menu`, `Select`, `Combobox`, `Checkbox`                    |
| Copy, then copied                      | `Copy`, then `Check`                                        | `CopyButton`                                                |
| Reveal and hide                        | `Eye` and `EyeOff`                                          | `SecretValue`                                               |
| Increase and decrease                  | `Plus` and `Minus`                                          | `NumberField`                                               |
| Information, success, caution, failure | `InfoCircle`, `CheckCircle`, `AlertTriangle`, `AlertCircle` | `Callout` and `Toast`                                       |

## Guidelines

### Pair Icons With Text

An icon beside a label speeds up recognition, and the label carries the meaning. Use an icon without text only for actions that are familiar without words, such as Close, Copy, and More.

Don't add icons to every item in a group. An icon on one button among several draws attention to that action.

### Size Icons With Their Text

Leave icons at `1em` beside text, so they scale with the type and stay aligned. A larger icon next to small text throws off the line and reads as a separate element.

**Do:** Let an inline icon inherit the size and color of its label.

**Don't:** Enlarge or recolor an inline icon apart from its text.

### Keep Icons in the Text Color

An icon in an accent color reads as a status. Keep icons in `foreground` or `gray.900`, and use intent colors only when the icon reports a status, as in `Callout` and `Toast`.

### Use Catalog Icons Only

Draw from `@tempoxyz/ds/icons` so stroke weight, corner style, and the 16 by 16 grid stay consistent. When the catalog lacks an icon, propose one in the Design System project with its use case rather than mixing in another set.

Token and network logos are not icons. Use `Token` for token logos and `Avatar` or `Identicon` for accounts.

## Accessibility

* Icons are decorative by default. Without `aria-label` or `aria-labelledby`, an icon renders `aria-hidden="true"`, so screen readers skip it.
* Give an icon `aria-label` only when it carries meaning that no nearby text states, such as a lone status icon. A labelled icon renders `role="img"`.
* Name icon-only buttons on the button, not the icon: `<Button aria-label="Copy address" shape="icon">`. Name the action, not the picture, so write Close dialog rather than X.
* Pair an icon-only button with a `Tooltip` that repeats its label, so sighted mouse users can read it too.
* Keep meaningful icons at 3:1 contrast or more against their background. `gray.900` and `foreground` pass on both backgrounds.
* In forced colors mode, `currentColor` follows the system text color, so icons stay visible without extra styles.

## Related

* [Button](/docs/components/button) for icon buttons and icons beside labels
* [Icon Chip](/docs/components/icon-chip) for framed icons in headers and lists
* [Tooltip](/docs/components/tooltip) for labelling icon buttons
* [Color](/docs/foundations/color) for icon colors
