Files
2026-05-27 23:29:53 +01:00

4.5 KiB

Tasks: enterprise-react-notifications

Change ID: enterprise-react-notifications Package: @suaveplan/react-notifications Target path: react/ui/react-notifications Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/react-translate


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal layout.
  • Write package.json at 0.1.0 with "sideEffects": ["**/*.css"], exports map (barrel + ./toast-manager + ./styles/notifications.css).
  • Dependencies: @suaveplan/error workspace:^, @suaveplan/react-translate workspace:^, class-variance-authority catalog:ui, clsx catalog:ui, lucide-react catalog:ui, tailwind-merge catalog:ui, zod catalog:forms, @opentelemetry/api catalog:observability, tslib catalog:build.
  • Write tsconfig.json, vitest.config.ts, scripts.

2. Error codes and types

  • Define NotificationError; code: NOTIFICATION_CONTEXT_MISSING.
  • Define all types: ToastVariant, ToastPosition, ToastOptions, ToastInstance, ToastManagerConfig, ToastEventType, ToastEvent, ToastEventListener, Notification, NotificationOptions, NotificationContextValue, NotificationProviderProps.

3. ToastManager (pure TS)

  • createToastManager(config?): ToastManager — event emitter; show(options): string, dismiss(id), dismissAll(), getAll(): ToastInstance[].
  • Auto-dismiss via globalThis.setTimeout; clears on dismiss()/dismissAll().
  • Emits ToastEvent typed events.
  • Write toast-manager.test.ts (≤500 lines): show/dismiss/dismissAll, auto-dismiss fires, config TTL. { timeout: 10000 }.
  • Write toast-manager.md.

4. NotificationProvider

  • Wraps ToastManager + notification history array in context.
  • useToastContext throws NotificationError(NOTIFICATION_CONTEXT_MISSING) outside provider.
  • Write test + md.

5. Hooks

useToast

  • Returns { toast(options): string, dismiss(id): void, toasts: ToastInstance[] } from context.
  • OTel notification.show span on toast() with notification.variant + notification.position.
  • Write use-toast.test.ts, stories (playground), md.

useNotifications

  • Returns persistent notification history + markRead(id), clearAll().
  • OTel notification.dismiss span on dismiss.
  • Write use-notifications.test.ts, md.

6. Components

Toast

  • CVA variants (success, error, warning, info, default); lucide-react icon per variant; dismiss button with useTranslation("Close").
  • Write test, stories (all-variants, playground), md.

ToastContainer

  • Positions: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right. Renders active toasts; portal to document.body.
  • Write test, stories (all-positions), md.

NotificationItem

  • Read/unread state badge, timestamp, body. Write test, md.

NotificationCenter

  • Drawer/popover listing notification history; mark-read / clear-all actions.
  • Write test, stories (with-history, empty, playground), md.

7. CSS

  • src/styles/notifications.css — toast animation (slide-in/out), prefers-reduced-motion disables animation.

8. E2E

  • e2e/notifications.spec.ts — Playwright:
    • Call toast({ message: 'Hello' }), verify toast appears.
    • Wait for auto-dismiss TTL, verify toast gone.
    • Click dismiss button, verify immediate removal.
    • Open NotificationCenter, verify history entry.

9. Verify and publish

  • bunx turbo lint typecheck test --filter=@suaveplan/react-notifications — green.
  • bunx turbo test:coverage --filter=@suaveplan/react-notifications — 100%.
  • bun scripts/publish.ts --package @suaveplan/react-notifications.
  • Archive change folder.