4.1 KiB
4.1 KiB
Tasks: enterprise-react-calendar
Change ID: enterprise-react-calendar
Package: @suaveplan/react-calendar
Target path: react/forms/react-calendar
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/events, @suaveplan/datetime, @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": false, exports map. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/events workspace:^,@suaveplan/datetime workspace:^,@suaveplan/react-translate workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build. - Write
tsconfig.json,vitest.config.ts, scripts.
2. Error codes and types
- Define
CalendarErrorextendingSuaveplanError; codes:CALENDAR_INVALID_EVENT,CALENDAR_VIEW_NOT_SUPPORTED. - Define all types in
src/types/calendar.types.ts:CalendarView,CalendarEvent,CalendarEventMap,CalendarConfig,CalendarProps,CalendarViewProps,CalendarHeaderProps,DateRange,NavigationDirection,UseCalendarReturn. - Write
CalendarEventSchemaZod schema.
3. Hook — useCalendar
- State:
view: CalendarView,currentDate: Date,events: Map<string, CalendarEvent[]>(keyed byyyyy-MM-dd). - Date math via
@suaveplan/datetimeaddDuration,startOf,endOf; optionaltimeZonein config. - Exposes:
navigate(direction: NavigationDirection),setView(view),addEvent(event),removeEvent(id),updateEvent(id, partial),getEventsForDate(date),getEventsForRange(start, end),visibleRange: DateRange. - Emits
@suaveplan/eventsevents:event:added,event:removed,event:updated,view:changed,navigation— uses@suaveplan/eventsEventBus. - OTel
calendar.navigatespan onnavigate(). - Write
use-calendar.test.tsx(≤500 lines): navigate months/weeks/days, add/remove/update events, getEventsForDate O(1) verified, timeZone option.{ timeout: 10000 }. - Write
use-calendar.md.
4. Components
CalendarHeader
- Prev/Next/Today buttons + view switcher.
useTranslationfor all copy. - Write test, stories (all-navigations, view-switching), md.
CalendarMonthView
- 6-week grid; renders
CalendarEventchips per day cell; handles overflow with "+N more". - Write test, stories (default, with-events, empty), md.
CalendarWeekView
- 7-column time grid; positions events by start/end time.
- Write test, stories, md.
CalendarDayView
- Single-day time grid.
- Write test, stories, md.
CalendarAgendaView
- List of upcoming events grouped by date.
- Write test, stories, md.
Calendar
- Composes Header + active view; controlled/uncontrolled;
"use client"at entry. - Write test, stories (month, week, day, agenda, with-events, empty, playground), md.
5. E2E
e2e/calendar.spec.ts— Playwright:- Click "Next" in month view, verify date header advances by 1 month.
- Add event programmatically, verify chip appears in correct day cell.
- Switch to week view, verify current week shown.
6. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-calendar— green.bunx turbo test:coverage --filter=@suaveplan/react-calendar— 100%.bun scripts/publish.ts --package @suaveplan/react-calendar.- Archive change folder.