Mercurial
view design_system/NOTIFICATIONS.md @ 269:de291f396881
install initial production config
Copy the ignored repository config into /etc/mrjunejune on first deployment while preserving existing production configuration on later deploys.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 13:08:10 -0700 |
| parents | 60a876c4587a |
| children |
line wrap: on
line source
# Zenbu UI notifications `zen-notifications` is a light-DOM, framework-free notification scope. Its stack is fixed to the bottom-right by default and styled only with `--zen-*` tokens. ```html <zen-notifications aria-label="Notifications"> <main id="application"></main> </zen-notifications> ``` ## Notify Descendants dispatch a bubbling, non-composed event: ```js source.dispatchEvent(new CustomEvent("zen-notify", { bubbles: true, composed: false, detail: { version: 1, id: "repository-removed", tone: "success", message: "Repository removed", description: "The local checkout was preserved.", announcement: "polite", durationMs: 5000, action: { token: "opaque-action-token", label: "Undo", }, }, })); ``` Fields: | Field | Values | | --- | --- | | `version` | must be `1` | | `id` | stable non-empty string | | `tone` | `info`, `success`, `warning`, or `error` | | `message` | required text | | `description` | optional text | | `announcement` | `none`, `polite`, or `assertive` | | `durationMs` | 250–120000; defaults to 5000 | | `persistent` | disables timeout when `true` | | `action` | opaque token and visible label | The same ID updates and moves the existing record instead of creating a duplicate. An ID is announced once during its current lifetime. ## Dismiss and actions Dismiss through the public method or a scoped event: ```js notifications.dismiss("repository-removed"); source.dispatchEvent(new CustomEvent("zen-dismiss-notification", { bubbles: true, composed: false, detail: { version: 1, id: "repository-removed" }, })); ``` Action buttons dispatch `zen-notification-action` with `{ version, id, token }`. The opaque token remains in private component state and is never written into DOM attributes or source markup. Removal dispatches `zen-notification-removed` with `{ version, id, reason }`. ## Bounds and timing - Three records are rendered. - Twenty additional records may remain queued. - The idle stack layers older records behind the newest with depth and scale. - Hovering the stack or focusing an action expands all visible records using their measured heights and first-party component code. - Overflow evicts the oldest finite record; all-persistent queues reject new records. - Queued records do not count down. - Finite timers pause while hovered, while focus remains inside, and while the document is hidden. - Disconnecting clears records, timers, announcements, and internal DOM. ## Accessibility - Polite and assertive announcements use separate persistent live regions. - Announcement priority is explicit and independent of tone. - Announcement messages are serialized so bursts remain observable. - Actions and dismissal use native buttons. - New notifications never move focus. - Keyed rendering preserves focused controls when unrelated records change. - Forced-colors and reduced-motion modes are supported by component CSS. Events with `composed: true` are rejected. This keeps nested application scopes isolated; adapters crossing a ShadowRoot must validate and redispatch a new non-composed event deliberately.