feat(ui-calendar-grid): new leaf package for the headless calendar-grid engine, extracted from @solu30/ui-kit (ADR-160, supersedes ADR-043/ADR-044)
Amendment 2026-07-11: renamed @solu30/calendar-grid → @solu30/ui-calendar-grid and moved to packages/ui/2-domain/calendar-grid/ pre-publish (ADR-160 amendment, ui-* naming convention) — the package never shipped to the registry, so this is a plain rename, not a breaking change to a published surface.
Rationale (see ADR-160): MonthGrid, DayCell, EventChip,
CalendarLegend, useCalendarNavigation (+ types) lived in @solu30/ui-kit
foundation layer per ADR-043 as a headless cross-vertical primitive. It has
2 real consumers today, found via a symbol-by-symbol cross-repo grep (not
just the composite BookingCalendar name, which is how the first pass
under-counted): GestorSalon's booking-calendar-view.tsx (via
<BookingCalendar>, event/venue booking) and luigi/apps/admin's
employee-month-view.tsx (via MonthGrid + CalendarLegend +
useCalendarNavigation directly, no <BookingCalendar> — an HR attendance
view, unrelated to booking domain). No other vertical imports any of these
symbols (TheCharterPanel, easycharter, prepchat, dietaly, EasyYachts,
pagebuilder, elliot, zentrya, carlosmartinpavon — all checked, all clean).
A first iteration of this changeset moved everything into
@solu30/booking-system (already the domain package for booking). Escalated to
Martín with 3 options once the non-booking consumer was found (move to
booking-system / new leaf package / partial split); Martín chose a new leaf
package, @solu30/ui-calendar-grid — his choice is the explicit OK for this
package's alta (non-delegable). This avoids forcing luigi/apps/admin to adopt
@solu30/booking-system's full peer-dependency contract (@trpc/server,
drizzle-orm, framer-motion, qrcode.react) purely to render a calendar
grid it doesn't otherwise need.
New package: @solu30/ui-calendar-grid (minor, first release)
Contains MonthGrid, DayCell, EventChip, CalendarLegend,
useCalendarNavigation, plus types (CalendarEvent, StatusConfigEntry,
StatusConfigMap, CalendarLegendItem, NavigationDirection,
UseCalendarNavigationReturn) and pure date utilities. peerDependencies:
react, react-dom, lucide-react, and @solu30/ui-kit (only for the cn
helper — no cycle). No @trpc/server/drizzle-orm/framer-motion/next. No
naming collision here — CalendarEvent keeps its original name (the
BookingCalendarEvent rename only applies at the @solu30/booking-system
boundary, see below).
Breaking change in @solu30/ui-kit (major)
BookingCalendar, MonthGrid, DayCell, EventChip, CalendarLegend,
useCalendarNavigation, and their associated types are removed from the
@solu30/ui-kit root export. No re-export shim: @solu30/booking-system
already depends on @solu30/ui-kit, so a shim would create a
foundation→domain→foundation cycle. Migration:
- import { BookingCalendar, type CalendarEvent } from "@solu30/ui-kit";
+ import { BookingCalendar } from "@solu30/booking-system";
+ import { type CalendarEvent, useCalendarNavigation, type StatusConfigMap, type CalendarLegendItem } from "@solu30/ui-calendar-grid";
Additive change in @solu30/booking-system (minor)
BookingCalendar (the composed, booking-flavored wrapper — same
alwaysScroll/mobile-scroll design from ADR-043/ADR-044, same
BookingCalendarProps public shape) stays here as
src/components/BookingCalendar.tsx, now composing MonthGrid +
CalendarLegend + date utilities from the new @solu30/ui-calendar-grid
dependency instead of owning them as local files. New peerDependency:
@solu30/ui-calendar-grid (optional: false, same treatment as @solu30/ui-kit).
Internally aliases the leaf's CalendarEvent as BookingCalendarEvent to avoid
confusion with this package's own CalendarEvent (the Google Calendar API
event shape) — no actual compile collision today since the raw grid pieces
are not re-exported from this package's root.
Consumer impact
2 real consumers today, both to be migrated as part of this release
(working trees edited, uncommitted, not built/typechecked):
saloneventos (GestorSalon) booking-calendar-view.tsx — BookingCalendar
from @solu30/booking-system; useCalendarNavigation, CalendarEvent,
StatusConfigMap, CalendarLegendItem from @solu30/ui-calendar-grid.
useIsMobile stays on @solu30/ui-kit (unrelated, not moved).
luigi/apps/admin employee-month-view.tsx — MonthGrid, CalendarLegend,
useCalendarNavigation, CalendarEvent (no prefix — the
BookingCalendarEvent rename does not apply outside booking-system),
StatusConfigMap, all from @solu30/ui-calendar-grid directly.
ChevronLeftIcon/ChevronRightIcon/EmptyState/IconButton/Spinner stay
on @solu30/ui-kit.
Gating: @solu30/ui-calendar-grid does not exist on the registry yet (new
package) and the published @solu30/booking-system does not yet compose it.
saloneventos and luigi will fail to build/typecheck against the current
registry state — expected, and not fixed locally. Those two verticals' commits
- lockfile bumps are gated to the coordinated publish sequence
(
ui-calendar-grid first release → booking-system minor → ui-kit major),
which needs Martín's explicit OK — not part of this changeset.