# ThemeColor

**When to use:** The `color` prop of every component that takes one: the theme's named colours, or any CSS colour of your own.

**Keywords:** colour, palette, tone, variant, status, semantic, danger, destructive, brand, custom

**Import:** `import { ThemeColor } from '@ahrowe/ui'`
**Types:** `import type { ColorValue } from '@ahrowe/ui'`

Every `color` prop in the library takes the same `ColorValue`: one of the six `ThemeColor`s, or
any CSS colour. A component's **style** (how much it stands out) is a separate prop, `styleType`,
so any style works in any colour.

```tsx
import { Badge, Button, ButtonStyleType, ThemeColor, showToast } from '@ahrowe/ui';

<Button styleType={ButtonStyleType.Filled} color={ThemeColor.Error}>Delete</Button>
<Badge count={3} color={ThemeColor.Success} />
showToast('Saved', { color: ThemeColor.Success });

// Any CSS colour, a theme variable included
<Button color="var(--brand)">Upgrade</Button>
<Badge content="Beta" color="#7c3aed" />
```

**Enums:**

- `ThemeColor`: `Primary` | `Neutral` | `Success` | `Info` | `Warn` | `Error`

| Colour | Reads | Notes |
|--------|-------|-------|
| `Primary` | `--primary-color`, `--text-on-primary`, `--primary-gradient` | The fill paints the gradient when the theme sets one |
| `Neutral` | the surrounding text colour, `--border-color` | Takes the colour of what it sits on: a close button on an Alert, a toolbar on a primary header. Its fill and tint are see-through mixes of that colour |
| `Success` | `--success-color` | |
| `Info` | `--info-color` | |
| `Warn` | `--warn-color` | |
| `Error` | `--error-color`, `--text-on-delete` | For destructive actions |

**Where it applies:** Button, ActionIcon, CopyButton, SplitButton, ActionButtons (`submitButtonColor`,
`cancelButtonColor`), Card and its actions, Badge, Chip, Accordion, Alert, Toast, Timeline items, Calendar
events, ProgressBar segments, Loader and AnimatedLogo.

**Styles share their names:** where two components offer the same look, it has the same name in
each one's own `styleType` enum. Each component offers only the ones it can draw.

| Style | Looks like | Offered by |
|-------|------------|------------|
| `Filled` | a solid fill, text in a contrasting colour | Button, Badge, Chip |
| `Light` | a light tint of the colour, text in the colour | Button, Badge, Chip, Accordion (its header), Card (its surface, text unchanged) |
| `Outlined` | a border and text in the colour | Button, Badge, Chip, Accordion, Card (its border, text unchanged) |
| `Plain` | text in the colour only | Button, ActionIcon, Accordion |

Alert, Toast and Timeline have a single look, so they take a `color` and no style.

**Which style to use.** Every component offers the same few, so the choice is about emphasis,
and a page stays consistent when each one means the same everywhere:

- `Filled`: the one main action of a region, and counts. At most one `Filled` per region.
- `Light`: status labels, a selected filter, secondary emphasis.
- `Outlined`: secondary actions and grouped content. The default for Button and Accordion.
- `Plain`: tertiary and toolbar actions, close buttons, a disclosure inside text.

**How each is drawn.** `Light` is a 22% see-through tint of the colour (8% of the text colour for
`Neutral`), the same for every colour. Text in the colour (`Light`, `Outlined`, `Plain`) is the
colour moved a third of the way toward the page's text colour in lightness, keeping its
saturation: the pure colour is often too faint to read as text, dark red on a dark theme most of
all. Borders, bars, dots and icons keep the pure colour. Text on a fill is black or white, see
below.

## A colour of your own

Pass any CSS colour. It replaces the theme's colour everywhere the component uses one, including
the hover tint and the gradient, which a colour of your own does not get:

```tsx
<Button styleType={ButtonStyleType.Filled} color="var(--brand)">Upgrade</Button>
```

**Text on a fill** is white wherever it reaches a contrast of 3:1 on the colour, otherwise black,
which then has at least 7:1: `color="#fde047"` gets black text and `color="#7c3aed"` white. On a
mid-tone blue that keeps white, which reads better there than black, though it can fall short of
WCAG's 4.5:1 for small text. It is worked out in CSS from the colour's relative luminance with
relative colour syntax, so a `var()` that changes with the theme changes its text with it.
A browser older than Chrome 119 or Firefox 128 gets `--text-on-primary` instead. To choose the
text yourself, set `color` in the component's `style` or a class. A built-in colour keeps the theme's own `--text-on-primary` or
`--text-on-delete`; a theme without them gets the same automatic choice.

**A value that can never be a colour** (`color="eror"`) logs a warning in development. A `var()`
cannot be checked until it renders.

**For a whole section or the app**, set the default rather than repeating it:
`defaultProps={{ Button: { color: 'var(--brand)' } }}` on `AhroweProvider`, or on a
`ConfigProvider` around the section ([ConfigProvider.md](ConfigProvider.md)). A default prop does
not change with the theme; for a colour that does, give each theme a variable of your own and
pass that: `color: 'var(--app-button)'`.

**A preset**, a fixed mix of props you use repeatedly, is a component in your app:

```tsx
export function DeleteIconButton(props: ActionIconProps) {
  return <ActionIcon color={ThemeColor.Error} icon={faTrash} {...props} />;
}
```
