4.5 KiB
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 statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin 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.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per proposal layout.
- Write
package.jsonat0.1.0with"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 ondismiss()/dismissAll(). - Emits
ToastEventtyped 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. useToastContextthrowsNotificationError(NOTIFICATION_CONTEXT_MISSING)outside provider.- Write test + md.
5. Hooks
useToast
- Returns
{ toast(options): string, dismiss(id): void, toasts: ToastInstance[] }from context. - OTel
notification.showspan ontoast()withnotification.variant+notification.position. - Write
use-toast.test.ts, stories (playground), md.
useNotifications
- Returns persistent notification history +
markRead(id),clearAll(). - OTel
notification.dismissspan 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 withuseTranslation("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 todocument.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-motiondisables 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.
- Call
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.