# Illustration

> Outline drawings of product screens, made from tokens, that mirror with the direction while their text stays readable.

Source: https://ritla.app/ui/illustration

## Installation

Installing from the registry is coming soon. Until then, these are the commands you will run.

```bash
npx ritla add illustration
```

With the shadcn CLI instead:

```bash
npx shadcn@latest add @ritla/illustration
```

## Usage

```tsx
import { IlBar, IlCard, IlText, IllustrationBackdrop, IllustrationSvg } from "@/components/ui/illustration";

<IllustrationBackdrop grid={20}>
  <IllustrationSvg width={240} height={120}>
    <IlCard x={20} y={10} width={200} height={100} />
    <IlText x={34} y={34} weight="semibold">New transfer</IlText>
    <IlBar x={34} y={48} width={120} />
  </IllustrationSvg>
</IllustrationBackdrop>
```

## Examples

### The parts

Every part as in the Figma sheet "Outline kit": Card with the hard shadow, Bar tones, Tag, Button, Divider, Avatar dot, Switch, the two Arrows, QR, Input, List row, Chart bars, Window and Bank card. In RTL the shadow, the switch knob, the Next arrow and the latest bar move; Swap, the numbers and the QR stay put.

Live preview: https://ritla.app/_kanz/preview/ltr/illustration-parts

### One codebase, both directions

`CodebaseIllustration`: one screen in both directions around an axis. It draws both directions itself, so it never mirrors with the page.

Live preview: https://ritla.app/_kanz/preview/ltr/illustration-codebase

### Figma variables

`VariablesIllustration`: each swatch paints the live token in its theme, whatever the page's theme. Figma's interface is English, so it stays left to right.

Live preview: https://ritla.app/_kanz/preview/ltr/illustration-variables

### Scan results

`ScanListIllustration`: the rows follow the page's direction with the count at the inline end; the domains stay left to right.

Live preview: https://ritla.app/_kanz/preview/ltr/illustration-scan-list

## API reference

### `IllustrationSvg`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `width / height` | `number` | None | The drawing's coordinate space, in left-to-right coordinates. The svg scales to its container's width. |
| `mirror` | `boolean` | `true` | Mirror the drawing about its centre line inside RTL. `false` for drawings with no reading direction. |
| `label` | `string` | None | With a label the drawing is an image with that name; without one it is decorative and hidden. |

### `IlCard`

`IlRect`, `IlBar`, `IlDot` and `IlLine` take the same position and colour props.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `x, y, width, height / cx, cy, r / x1, y1, x2, y2` | `number` | None | Position and size in drawing units. |
| `fill / stroke` | `IllustrationTone` | None | A palette name; every one is a token. The default outline is `border/brand/dim`. |
| `radius` | `number` | None | Corner radius. |
| `elevation / onBrand` | `"none" \| "hard" / boolean` | `"none"` | `IlCard`: the hard shadow, 6 toward the inline end and 6 down (bottom-left in RTL), and the deeper one on the sky band. |
| `dashed` | `boolean` | None | Dashed, for construction lines such as the mirror axis. |

### `IlText`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `anchor` | `"start" \| "end" \| "middle"` | `"start"` | Which edge of the text sits on `x`, as drawn in LTR. In RTL that edge stays on the mirrored `x`. |
| `size / weight / fill` | `number / Weight / IllustrationTone` | None | Font size, weight and color; never letter-spaced. |
| `mono` | `boolean` | None | Monospace, for code and domains. |

### `IlArrow`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `kind` | `"next" \| "swap"` | `"next"` | `next` points to the inline end and mirrors; `swap` (an exchange) never mirrors. |
| `badge` | `boolean` | None | In a brand circle as in Figma; without it, the bare glyph inside a button. |
| `toward` | `"end" \| "start"` | `"end"` | `start` for an arrow pointing back, in a drawing that shows both directions. |

### `IlSwitch`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `on` | `boolean` | None | On puts the knob at the inline end. |

### `IlInput`

`IlListRow`, `IlTag` and `IlButton` work the same way.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value / tag` | `ReactNode` | None | The value (always upright) and the tag at the inline end. |

### `IlChartBars`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `values` | `number[]` | None | Oldest first, the latest in brand. The homepage illustrations and the KPI stat follow the reading direction, so in Arabic the oldest is at the start (right) and the latest at the end (left). |

### `IlWindow`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `elevation / onBrand` | `"none" \| "hard" / boolean` | None | The hard shadow as on `IlCard`, and the deeper one on the sky band. |

### `IlBankCard`

`IlQr` never mirrors either.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `last4 / pattern` | `string` | None | The last four digits, and the QR's pattern. |

### `Upright`

`IlCheck` never mirrors either.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children / x, y, size` | `ReactNode / number` | None | The check never mirrors, and `Upright` keeps a whole group from mirroring. |

### `CodebaseIllustration`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label / startTag / endTag` | `string` | None | The chip on the axis and the two screens' tags. |

### `VariablesIllustration`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `rows / labels` | `VariableRow[] / { variable; light; dark; direction }` | None | The variable rows and the column words. |

### `ScanListIllustration`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `rows / caption` | `ScanRow[] / ReactNode` | None | The pages scanned with their finding counts, and the line under them. |

### `IllustrationBackdrop`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `grid` | `16 \| 20 \| 40` | `20` | The construction grid's cell: 16 for small tiles, 20 for cards, 40 for the hero. |
| `surface` | `"sky" \| "none"` | `"sky"` | `sky` paints the band (`background/brand/faint`); `none` draws only the grid. |
| `fade` | `boolean` | None | Fade the grid out from the centre. |

## Accessibility

ARIA:

- A drawing is decorative and hidden unless it has a `label`; then it is read as an image with that name.
- The grid is decoration only and takes no pointer events.

## Arabic and RTL notes

Mirrors:

- The whole layout, about its centre line: avatars, labels and buttons move to the other side.
- The arrow follows the language, and in the homepage illustrations and the KPI stat time runs with the reading direction.

Does not mirror:

- Text, numbers and checkmarks read normally, each text keeping to the inline start of its row on the mirrored side.
- A phone number row, logos and media controls, inside `Upright`.

Numerals: Numbers in a drawing always read left to right: the svg lays text out left to right.

Arabic typography: The font follows the nearest `lang`, Geist or IBM Plex Sans Arabic, and Arabic is never letter-spaced.
