first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
# Alert
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs --> - alert.variants — `alertVariants` is the cva config……
- [alert.variants](./alert.variants.md) — `alertVariants` is the cva config that powers the `<Alert>` chassis component. It exposes a `variant` axis with four ru…
- alert.variants — `alertVariants` is the cva config……
- [alert.variants](./alert.variants.md) — `alertVariants` is the cva config that powers the `<Alert>` chassis component. It exposes a `variant` axis with four ru…
- alert.variants — `alertVariants` is the cva config……
- [alert.variants](./alert.variants.md) — `alertVariants` is the cva config that powers the `<Alert>` chassis component. It exposes a `variant` axis with four ru…
- alert.variants — `alertVariants` is the cva config…
- [alert.variants](./alert.variants.md) — `alertVariants` is the cva config that powers the `<Alert>` chassis component. It exposes a `variant` axis with four ru…
- [alert.variants](./alert.variants.md) — `alertVariants` is the cva config that powers the `<Alert>` chassis component. It exposes a `variant` axis with four ru…
## Purpose
`<Alert>` is the chassis callout for inline messages, errors, and notices. It ships as a family of four components — `<Alert>` (root), `<AlertTitle>`, `<AlertDescription>`, `<AlertIcon>` — that compose into the conventional shadcn alert layout. Per the shadcn skill rule, ALWAYS use `<Alert>` for callouts rather than building custom styled divs (`<div className="border-l-4 border-yellow-500 ...">`) — hand-rolled callouts diverge across teams in colour scale, iconography, accessibility hooks, and dark-mode treatment.
The chassis renders `role="alert"` on the root so screen-readers announce the message. The `variant` axis swaps semantic colour pairs for four rungs (`default` / `destructive` / `success` / `warning`), and `<AlertIcon>` selects the matching lucide-react icon (`InfoIcon` / `AlertCircleIcon` / `CheckCircle2Icon` / `AlertTriangleIcon`) for the variant.
## Features
- Four colour variants via the `variant` axis (`default` / `destructive` / `success` / `warning`).
- Four composition primitives — `Alert`, `AlertTitle`, `AlertDescription`, `AlertIcon`.
- `role="alert"` automatically applied so screen-readers announce the message.
- `data-variant` attribute on the rendered root so tests / consumer CSS can target alerts by variant.
- `[&>svg]:` Tailwind arbitrary modifiers position any direct svg child as an inline icon — no consumer flex setup required.
- `<AlertTitle>` renders as `<h5>` so it nests under page-level headings without disrupting the document outline.
- `<AlertDescription>` renders as `<div>` so consumers can compose paragraphs / lists / inline elements without nesting block elements inside a `<p>`.
- All sub-components forward refs to their underlying DOM nodes.
## Usage: Basic Example
```tsx
import {
Alert,
AlertDescription,
AlertIcon,
AlertTitle,
} from "@suaveplan/react-ui";
export function PolicyChange() {
return (
<Alert variant="warning">
<AlertIcon variant="warning" />
<AlertTitle>Policy update</AlertTitle>
<AlertDescription>
Your team's retention policy has been updated.
</AlertDescription>
</Alert>
);
}
```
## Usage: Advanced Example
```tsx
import {
Alert,
AlertDescription,
AlertTitle,
Button,
} from "@suaveplan/react-ui";
import { ZapIcon } from "lucide-react";
export function CustomIconAlert() {
return (
<Alert variant="success">
<ZapIcon className="size-4" aria-hidden="true" />
<AlertTitle>Sync complete</AlertTitle>
<AlertDescription>
<p>523 records synchronised in 1.4 seconds.</p>
<Button variant="outline" size="sm" className="mt-2">
View report
</Button>
</AlertDescription>
</Alert>
);
}
```
## API Reference
### `<Alert>`
`forwardRef<HTMLDivElement, AlertProps>` — root container. Renders `role="alert"` and `data-variant`.
| Prop | Type | Default | Description |
|---|---|---|---|
| `variant` | `"default" \| "destructive" \| "success" \| "warning"` | `"default"` | Colour palette. |
| _all_ `HTMLAttributes<HTMLDivElement>` | _native_ | _native_ | Forwarded as-is. |
### `<AlertTitle>`
`forwardRef<HTMLHeadingElement, AlertTitleProps>` — heading rendered as `<h5>`.
### `<AlertDescription>`
`forwardRef<HTMLDivElement, AlertDescriptionProps>` — body text. Rendered as `<div>` to allow nested block elements.
### `<AlertIcon>`
`function (props: AlertIconProps): ReactElement` — convenience wrapper that renders the lucide-react icon for the supplied `variant`. Marked `aria-hidden="true"` so the visible title / description carries the accessible name. Not a `forwardRef` (icons are stateless and the parent `<Alert>` reaches them via the cva `[&>svg]:` modifiers, not via ref-based DOM access).
| Prop | Type | Default | Description |
|---|---|---|---|
| `variant` | same as `<Alert>` | `"default"` | Variant whose default icon to render. |
| `className` | `string` | _undefined_ | Optional className passed to the rendered icon. |
#### Errors
The Alert components do NOT call `useTranslation()` so they do not interact with the i18n provider. Children carrying user-perceivable text must be resolved at the call site with `t('react-ui.alert.policy.title')` or similar.
## Implementation Notes
- `role="alert"` is unconditionally applied. This may produce verbose announcements when many alerts mount at once (e.g. a list of validation errors); consumers in that scenario should wrap the whole list in `<div role="alert" aria-live="polite">` and pass `role="presentation"` to each `<Alert>` to suppress duplicate announcements (or use `<Alert>` purely for visual styling and let the parent live region carry the accessibility semantics).
- The `[&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4` rules in the cva position any direct SVG child as the inline icon. This means consumers can drop any icon — `<MailIcon />`, `<SparklesIcon />`, `<AlertIcon variant="warning" />` — directly inside the alert root and it lands correctly without a wrapper element.
- `<AlertIcon>` is a convenience wrapper, not a required slot. Alerts without any icon (just title + description) render correctly — the magic-modifier rules only fire when a direct SVG child exists.
- `<AlertTitle>` defaults to `<h5>` because alerts typically appear inside a section that already has its own `<h2>` / `<h3>` heading. Consumers needing a different heading level should compose their own heading element with `alertTitleVariants()`.
- `<AlertDescription>` renders as `<div>` (not `<p>`) so consumers can compose nested block elements (paragraphs, lists, buttons) without invalid HTML — paragraphs cannot contain block elements.