[scheduler] Add viewConfig prop to limit displayed hours in the day and week views#22929
Conversation
…ek views Adds a new public `viewConfig` prop to the Event Calendar (and standalone views), keyed by view name. The `day` and `week` time-grid views accept `startTime`/`endTime` (whole hours, 0-24) to limit the displayed hour range. Renames the internal "view config" concept to "view definition" to free up the `viewConfig` name for the public API. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Deploy previewBundle sizeℹ️ Using snapshot from parent commit d575a01 (fallback from merge base 0cb49d9).
Check out the code infra dashboard for more information about this PR. |
There was a problem hiding this comment.
Nice work 🙌, left a few things from a review pass, leading with a rendering bug that's visible in the new demo itself.
🔴 Events fully outside the hour range still render (visible in the Week demo)
In WeekViewStartEndTime (window 8–20), the Morning Run occurrence at 07:00–07:45 still shows up as a thin bar pinned to the top of the column, labeled "Morning Run 7:00 AM". TimeGridColumn feeds all of day.withoutPosition into useEventOccurrencesWithTimelinePosition without intersecting them against [startTime, endTime), so an out-of-window occurrence gets clamped to duration: 0 / position: 0 but is still in the DOM — and minHeight: 11.5 in TimeGridEventShared makes it a visible sliver with a misleading time.
Two consequences:
- a ghost event renders at the top edge with the wrong displayed time;
- it still counts toward
maxIndex/--columns-count, so a genuinely-visible event in the same column can be squeezed into a narrower lane for no apparent reason.
Occurrences that only partially overlap the window should keep clamping (that part works), but ones entirely before startTime or after endTime shouldn't be placed at all.
🟡 DST-day misalignment from deriving minutes out of elapsed time
In CalendarGridTimeColumn, dayStartMinute/dayEndMinute are computed from real elapsed time (adapter.getTime(end) - startOfDayMs), but event positions use wall-clock minutesInDay and the grid renders whole-hour rows (hoursCount = endTime - startTime). On a DST-transition day the derived dayMinutes becomes 1380/1500 while the rows stay whole-hour, so events and the current-time indicator drift off the grid lines. This also regresses the default full-day view on those days (it used a fixed 1440 before). The minute offsets really want to come from the whole-hour window itself rather than be reverse-engineered from the dates.
🟡 Keyboard event creation can land outside the window
triggerKeyboardCreation anchors at setHours(start, 12) (noon), ignoring the range. With e.g. { startTime: 13, endTime: 20 }, pressing Enter on the column creates an event at 12:00 — outside the visible window, so it renders clamped with the wrong time.
🟡 Tests
- The new test files (
getTimeGridHourRange.test.ts,DayTimeGrid.viewConfig.test.tsx) don't follow the repo'sit('should …')convention. - Coverage gaps worth adding: clamped height (not just
--y-position), current-time-indicator hidden when out of range, theendTime === 24/startTime === 0branches inTimeGridColumn, drag/creation inside a limited window, and thestartTime === endTimevalidation case.
ℹ️ Minor
EventCalendarStore.ts:202still warns "No config found for the current view. Please useuseInitializeView" — stale after the config→definition rename (the hook isuseEventCalendarView).- In
TimeGridColumn, thestartmemo'sstartTime === 0branch is equivalent tosetHours(startOfDay, 0), so the ternary is redundant (theendTime === 24one isn't — keep that).
ℹ️ API design (worth deciding before it ships)
viewConfigis accepted on views that ignore it (month/agenda) and with the wrong key on single-view standalone views — it type-checks and silently no-ops, with no hint to the user.
- Skip occurrences entirely outside the visible window so they no longer
render as clamped slivers or inflate the column lane count.
- Derive the day minute offsets from the whole-hour window (passed as props)
instead of elapsed time, fixing DST-day misalignment.
- Clamp keyboard event creation to the visible window.
- Fix the stale "useInitializeView" warning and drop the redundant
startTime === 0 ternary.
- Follow the it('should …') test convention and add coverage for
out-of-window events, clamped height, and the startTime === endTime case.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
Thanks for the review 🙌 — addressed the feedback in edc3bda. 🔴 Events fully outside the hour range still render
🟡 DST-day misalignmentRemoved the elapsed-time derivation of 🟡 Keyboard creation landing outside the window
🟡 Tests
ℹ️ Minor
Still open for discussion
🤖 Generated with Claude Code |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
…nfig-start-end-time # Conflicts: # packages/x-scheduler-internals/src/use-event-calendar-view/useEventCalendarView.ts # packages/x-scheduler/src/agenda-view/AgendaView.tsx # packages/x-scheduler/src/compact-day-view/CompactDayView.tsx # packages/x-scheduler/src/compact-three-day-view/CompactThreeDayView.tsx # packages/x-scheduler/src/compact-week-view/CompactWeekView.tsx # packages/x-scheduler/src/day-view/DayView.tsx # packages/x-scheduler/src/internals/utils/day-time-grid-view-definition.ts # packages/x-scheduler/src/month-view/MonthView.tsx # packages/x-scheduler/src/week-view/WeekView.tsx
|
Thanks for laying out the options 🙌 API design — let's tighten the per-view types rather than add a runtime warning. Keep
Same per-view type-refinement idea as Otherwise this looks good to me 🥇 |
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
@rita-codes done ✔️ |
|
One gap! the standalone compact views (
|
|
If the compact views are not available within the EventCalendar for now, I would just omit the By the way, I think those standalone compact views should be exported as unstable because we don't know what the end DX will be. |
that sounds reasonable to me! cc @noraleonte |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
…nfig-start-end-time # Conflicts: # packages/x-scheduler-premium/src/agenda-view-premium/AgendaViewPremium.types.ts # packages/x-scheduler-premium/src/day-view-premium/DayViewPremium.types.ts # packages/x-scheduler-premium/src/month-view-premium/MonthViewPremium.types.ts # packages/x-scheduler-premium/src/week-view-premium/WeekViewPremium.types.ts # packages/x-scheduler/src/agenda-view/AgendaView.types.ts # packages/x-scheduler/src/day-view/DayView.types.ts # packages/x-scheduler/src/month-view/MonthView.types.ts # packages/x-scheduler/src/week-view/WeekView.types.ts
The compact views cannot yet be opted into within the EventCalendar, so their standalone props should not expose viewConfig. Omit it for now; it can be added back once these views become configurable from the calendar. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Changelog
Add a new
viewConfigprop to the Event Calendar, keyed by view name, so each view can receive its own configuration.For the
dayandweektime-grid views,viewConfigacceptsstartTimeandendTime(whole hours between0and24) to limit the hours displayed in the time grid:Closes #19952
Details
New public
viewConfigprop onEventCalendar,EventCalendarPremium, and the standalone day/week views (and their premium counterparts).The
dayandweekviews render only the configured hour window: the time axis, grid height, event/placeholder/current-time-indicator positioning, and drag-and-drop / event creation all respect the range.The internal "view config" concept (the per-view runtime behavior each view registers —
siblingVisibleDateGetter/visibleDaysSelector) is renamed to "view definition" to free up theviewConfigname for this public API.startTime/endTimemust be whole hours; minute-level precision isn't supported yet (documented with a callout and in the JSDoc).Added unit tests (range validation, axis-row count, event positioning, clamping, per-view key selection) and two documentation demos under the Week and Day view sections.
I have followed (at least) the PR section of the contributing guide.
🤖 Generated with Claude Code