49 lines
3.0 KiB
Plaintext
49 lines
3.0 KiB
Plaintext
---
|
|
description: Unified Alert (toast/banner) for app notifications — Figma + drift prevention
|
|
globs: app/**/*.tsx, stories/modals/Alert.stories.js, tests/components/Alert.test.tsx
|
|
alwaysApply: false
|
|
---
|
|
|
|
# Alerts and notifications
|
|
|
|
## Source of truth
|
|
|
|
- **Figma:** [Community Rule System — Modal / Alert](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=6351-14646) (node **6351-14646**).
|
|
- **Code:** `app/components/modals/Alert` — default export `Alert` from `Alert.container.tsx` (Figma docstring on the container).
|
|
|
|
## When to use `Alert`
|
|
|
|
Use **`Alert`** for **app-level, section-level, and shell-level** success, warning, error, and neutral status messages that should read as a designed system surface (not body copy alone).
|
|
|
|
Do **not** recreate the same job with ad-hoc UI: bordered `<p>`, free-standing `role="alert"` blocks, or raw `text-[var(--color-border-default-utility-negative)]` paragraphs for product messaging.
|
|
|
|
## Props (lowercase in code; match Figma intent)
|
|
|
|
| Concern | Prop | Notes |
|
|
| --- | --- | --- |
|
|
| Layout | `type` | `toast` — bottom accent bar, top rounded corners; `banner` — full rounded block, inline or stacked. |
|
|
| Intent | `status` | `default` \| `positive` \| `warning` \| `danger`. |
|
|
| Density | `size` | `s` \| `m` (Figma S/M). Typography and padding are implemented inside `Alert.container.tsx` — do not fork spacing per call site. |
|
|
| Copy | `title`, `description?` | Required title; optional description when `hasBodyText` is true. |
|
|
| Icon | `hasLeadingIcon?` | Default `true`. |
|
|
| Body | `hasBodyText?` | Default `true`; set `false` for title-only. |
|
|
| Dismiss | `onClose?`, `hasTrailingIcon?` | Close control shows only when `onClose` is provided **and** `hasTrailingIcon` is not `false`. Omit `onClose` for non-dismissible messages. |
|
|
|
|
Valid enum slices for Storybook / guards: `ALERT_*_OPTIONS` in `lib/propNormalization.ts`.
|
|
|
|
## Choosing toast vs banner
|
|
|
|
- **`toast`** — transient edge / bottom emphasis (e.g. completed flow), strong bottom border accent.
|
|
- **`banner`** — rounded block; for **page / shell / modal** messaging, mount inside a **`fixed`** (or equivalent) overlay wrapper with `pointer-events-none` on the outer layer and `pointer-events-auto` on the alert so layout chrome does not reflow when the message appears (see `CreateFlowLayoutClient` `topBanners`, profile overlays, `LoginForm`, `PostLoginDraftTransfer`).
|
|
|
|
## Exemptions (do not force `Alert`)
|
|
|
|
1. **Single-field validation** under a control — keep `TextInput` / `TextArea` `error` and helper text (e.g. invalid email on the login form) unless design explicitly moves that line into `Alert`.
|
|
2. **Marketing layout** — `HeroBanner`, `ContentBanner` are not system alerts.
|
|
3. **Landmarks** — `role="banner"` on headers/nav is not the `Alert` “banner” type.
|
|
4. **A11y-only live regions** — e.g. tooltip / incrementer `aria-live` for widget state, not product notifications.
|
|
|
|
## Copy
|
|
|
|
All user-visible strings go through **`messages/`** and `useTranslation` / message modules per `localization.mdc`.
|