feat(react-calendar-preview): implement Calendar, month/year pickers, and day grid components - #36629
Open
Dmytro Kirpa (dmytrokirpa) wants to merge 2 commits into
Open
Conversation
This was referenced Aug 25, 2026
|
Pull request demo site: URL |
Dmytro Kirpa (dmytrokirpa)
force-pushed
the
calendar-preview-impl
branch
from
August 25, 2026 20:08
3fa04eb to
1addb6b
Compare
Dmytro Kirpa (dmytrokirpa)
force-pushed
the
calendar-preview-impl
branch
from
August 29, 2026 08:52
1addb6b to
c3ef67b
Compare
Dmytro Kirpa (dmytrokirpa)
marked this pull request as ready for review
August 29, 2026 08:55
Copilot started reviewing on behalf of
Dmytro Kirpa (dmytrokirpa)
August 29, 2026 08:57
View session
Contributor
There was a problem hiding this comment.
Pull request overview
This PR (stack PR 2/3) turns the scaffolded @fluentui/react-calendar-preview package into a functional Calendar component family (day grid + month/year pickers), including supporting date utilities, contexts/hooks, tests, and Storybook stories, and wires the package into apps/public-docsite-v9.
Changes:
- Add Calendar implementation (contexts, hooks, utilities, and
Calendar*component/subcomponent set) following the v9 hook/slot architecture. - Add tests (unit + motion) and Storybook stories/docs for the preview Calendar scenarios.
- Add docsite dependency + lockfile updates and include a Beachball change file.
Reviewed changes
Copilot reviewed 152 out of 153 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Adds workspace dependency entry for @fluentui/react-calendar-preview referenced by docsite. |
| apps/public-docsite-v9/package.json | Adds @fluentui/react-calendar-preview dependency for docsite consumption. |
| change/@fluentui-react-calendar-preview-a1b2c3d4-0002-4000-8000-000000000002.json | Beachball change entry for the package update. |
| packages/react-components/react-calendar-preview/stories/src/index.ts | Removes placeholder comment now that stories exist. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/index.stories.tsx | Registers Calendar preview stories + docs content. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarDefault.stories.tsx | Default Calendar story entrypoint. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarMonthOnly.stories.tsx | Story demonstrating month/year picker-only usage. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarOverlaidMonthPicker.stories.tsx | Story for overlay month picker mode. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarDateBoundaries.stories.tsx | Story covering min/max/restricted dates. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarSixWeeks.stories.tsx | Story demonstrating fixed 6-week display. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarWeekNumbers.stories.tsx | Story enabling week numbers. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarWeekSelection.stories.tsx | Story for week range selection. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarMarkedDays.stories.tsx | Story demonstrating marked days callback. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarMonthSelection.stories.tsx | Story for month-range selection. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarMultiDayView.stories.tsx | Story for multi-day day-view selection. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarContiguousWork.stories.tsx | Story for contiguous work-week selection. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarNonContiguousWorkWeekDays.stories.tsx | Story for non-contiguous work-week days selection. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarLocalizedFormatting.stories.tsx | Story showing Intl-backed date/label formatting helpers. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarDescription.md | Component description for Storybook docs tab. |
| packages/react-components/react-calendar-preview/stories/src/Calendar/CalendarBestPractices.md | Usage guidance including label/date formatting patterns. |
| packages/react-components/react-calendar-preview/library/tsconfig.cy.json | Cypress TS config for package-level interaction tests. |
| packages/react-components/react-calendar-preview/library/cypress.config.ts | Cypress config using shared base config. |
| packages/react-components/react-calendar-preview/library/bundle-size/Calendar.fixture.js | Bundle-size fixture for Calendar import. |
| packages/react-components/react-calendar-preview/library/src/utils/index.ts | Barrel export for new calendar utilities. |
| packages/react-components/react-calendar-preview/library/src/utils/focus.ts | Adds focusAsync helper used by Calendar focus management. |
| packages/react-components/react-calendar-preview/library/src/utils/dataAttributes.ts | Adds boolean-to-presence data attribute helper. |
| packages/react-components/react-calendar-preview/library/src/utils/constants.ts | Calendar constants/types (days/months/range types/time constants). |
| packages/react-components/react-calendar-preview/library/src/utils/dateMath/index.ts | Barrel export for date-math helpers. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/index.ts | Barrel export for day-grid helpers. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/dateGrid.types.ts | Types for day grid generation and restrictions. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/getDayGrid.ts | Generates the day grid data structure for rendering. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/getBoundedDateRange.ts | Bounds selection ranges by min/max. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/getDateRangeTypeToUse.ts | Normalizes range type (e.g. non-contiguous workWeek → week). |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/findAvailableDate.ts | Finds nearest available date under restrictions. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/isRestrictedDate.ts | Restriction predicate using min/max/restricted dates. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/isBeforeMinDate.ts | Predicate helper for min date. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/isAfterMaxDate.ts | Predicate helper for max date. |
| packages/react-components/react-calendar-preview/library/src/utils/dateGrid/isContiguous.ts | Contiguity helper for work week day sets. |
| packages/react-components/react-calendar-preview/library/src/utils/dateFormatting/index.ts | Barrel export for date/label formatting. |
| packages/react-components/react-calendar-preview/library/src/utils/dateFormatting/dateFormatting.types.ts | Typed label/date formatting contracts. |
| packages/react-components/react-calendar-preview/library/src/utils/dateFormatting/dateFormatting.defaults.ts | Default English formatters + formatter factories. |
| packages/react-components/react-calendar-preview/library/src/utils/dateFormatting/dateFormatting.test.ts | Unit coverage for formatting defaults/factories. |
| packages/react-components/react-calendar-preview/library/src/utils/calendarMotions.test.tsx | Unit coverage for directional motion wrapper behavior. |
| packages/react-components/react-calendar-preview/library/src/testing/isConformant.ts | Conformance test wrapper for package components. |
| packages/react-components/react-calendar-preview/library/src/hooks/index.ts | Barrel export for calendar-specific hooks. |
| packages/react-components/react-calendar-preview/library/src/hooks/useWeeks.ts | Builds memoized week/day data including selection callbacks. |
| packages/react-components/react-calendar-preview/library/src/hooks/useWeekCorners.ts | Computes rounded-corner metadata for contiguous hover/selection. |
| packages/react-components/react-calendar-preview/library/src/hooks/useAnimateBackwards.ts | Detects backwards navigation for motion direction. |
| packages/react-components/react-calendar-preview/library/src/hooks/useCalendarPickerStyles.styles.ts | Shared month/year picker chrome styles. |
| packages/react-components/react-calendar-preview/library/src/hooks/useCalendarItemStyles.styles.ts | Shared item button styles for month/year grids. |
| packages/react-components/react-calendar-preview/library/src/contexts/index.ts | Barrel export for calendar contexts. |
| packages/react-components/react-calendar-preview/library/src/contexts/calendarContext.ts | Shared Calendar configuration context + defaults. |
| packages/react-components/react-calendar-preview/library/src/contexts/calendarDayContext.ts | Day-grid shared context (weeks, refs, navigation, etc). |
| packages/react-components/react-calendar-preview/library/src/contexts/calendarMonthContext.ts | Month-grid shared context (rows, navigated refs). |
| packages/react-components/react-calendar-preview/library/src/contexts/calendarYearContext.ts | Year-grid shared context (rows, current/selected refs). |
| packages/react-components/react-calendar-preview/library/src/components/Calendar/index.ts | Barrel export for Calendar component internals. |
| packages/react-components/react-calendar-preview/library/src/components/Calendar/Calendar.tsx | Calendar component composition (hook + styles + render). |
| packages/react-components/react-calendar-preview/library/src/components/Calendar/useCalendarContextValues.ts | Memoizes Calendar context values. |
| packages/react-components/react-calendar-preview/library/src/components/Calendar/renderCalendar.tsx | Provides Calendar context + lays out pickers/buttons. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/index.ts | Barrel export for CalendarMonth. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/CalendarMonth.tsx | Month picker component composition. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/renderCalendarMonth.tsx | Renders either month grid or nested year picker. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/useCalendarMonthContextValues.ts | Publishes month context values. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/useCalendarMonthStyles.styles.ts | Month picker styles. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonth/CalendarMonth.test.tsx | Unit coverage for localization + grid structure invariants. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonthGridRow/** | Month grid row component + motion slot support. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarMonthGridCell/** | Month grid cell component implementation + styling. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYear/index.ts | Barrel export for CalendarYear. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYear/CalendarYear.tsx | Year picker component composition. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYear/renderCalendarYear.tsx | Renders header/nav + year grid under provider. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYear/useCalendarYearContextValues.ts | Publishes year context values. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYear/useCalendarYearStyles.styles.ts | Year picker styles. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYearGridRow/** | Year grid row component + motion slot support. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarYearGridCell/** | Year grid cell component implementation + styling. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDay/index.ts | Barrel export for CalendarDay. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDay/CalendarDay.tsx | Day picker component composition. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDay/renderCalendarDay.tsx | Renders header/nav + grid body under provider. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDay/useCalendarDayContextValues.ts | Publishes day context values. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDay/useCalendarDayStyles.styles.ts | Day picker styles. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDayGridRow/** | Week row component with transition/motion support. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDayGridCell/** | Day cell component structure (root/button/label/marker). |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDayGridHeaderRow/** | Weekday header row component. |
| packages/react-components/react-calendar-preview/library/src/components/CalendarDayGridHeaderCell/** | Header cell component with optional fade motion. |
| packages/react-components/react-calendar-preview/library/src/Calendar.ts | Public export surface for Calendar. |
| packages/react-components/react-calendar-preview/library/src/CalendarDay.ts | Public export surface for CalendarDay. |
| packages/react-components/react-calendar-preview/library/src/CalendarMonth.ts | Public export surface for CalendarMonth. |
| packages/react-components/react-calendar-preview/library/src/CalendarYear.ts | Public export surface for CalendarYear. |
| packages/react-components/react-calendar-preview/library/src/CalendarDayGridCell.ts | Public export surface for day grid cell subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarDayGridRow.ts | Public export surface for day grid row subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarDayGridHeaderCell.ts | Public export surface for header cell subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarDayGridHeaderRow.ts | Public export surface for header row subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarMonthGridCell.ts | Public export surface for month grid cell subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarMonthGridRow.ts | Public export surface for month grid row subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarYearGridCell.ts | Public export surface for year grid cell subcomponent. |
| packages/react-components/react-calendar-preview/library/src/CalendarYearGridRow.ts | Public export surface for year grid row subcomponent. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+41
to
+46
| 'aria-label': month.ariaLabel, | ||
| 'aria-selected': month.isNavigated, | ||
| 'data-current': stringifyDataAttribute(month.isCurrent), | ||
| 'data-selected': stringifyDataAttribute(month.isSelected), | ||
| 'data-outside-bounds': stringifyDataAttribute(!month.isInBounds), | ||
| tabIndex: month.isInBounds ? 0 : -1, |
Comment on lines
+13
to
+31
| if (element) { | ||
| // An element was already queued to be focused, so replace that one with the new element | ||
| if (targetToFocusOnNextRepaint) { | ||
| targetToFocusOnNextRepaint = element; | ||
| return; | ||
| } | ||
|
|
||
| targetToFocusOnNextRepaint = element; | ||
|
|
||
| if (win) { | ||
| // element.focus() is a no-op if the element is no longer in the DOM, meaning this is always safe | ||
| win.requestAnimationFrame(() => { | ||
| targetToFocusOnNextRepaint && targetToFocusOnNextRepaint.focus(); | ||
|
|
||
| // We are done focusing for this frame, so reset the queued focus element | ||
| targetToFocusOnNextRepaint = undefined; | ||
| }); | ||
| } | ||
| } |
Comment on lines
+11
to
+16
| root: { | ||
| boxSizing: 'content-box', | ||
| overflow: 'hidden', | ||
| padding: '12px', | ||
| width: '196px', | ||
| }, |
Comment on lines
+32
to
+36
| const weeks = React.useMemo((): DayInfo[][] => { | ||
| const weeksGrid = getDayGrid(props); | ||
|
|
||
| const firstVisibleDay = weeksGrid[1][0].originalDate; | ||
| const lastVisibleDay = weeksGrid[weeksGrid.length - 1][6].originalDate; |
Comment on lines
+26
to
+31
| const useRootStyles = makeStyles({ | ||
| base: { | ||
| boxSizing: 'content-box', | ||
| padding: '12px', | ||
| width: '196px', | ||
| }, |
| CalendarMonthSelection.parameters = { | ||
| docs: { | ||
| description: { | ||
| story: 'A Calendar Compat allows you to set a selection range of months instead of selecting a single day.', |
| CalendarMonthOnly.parameters = { | ||
| docs: { | ||
| description: { | ||
| story: 'A Calendar Compat allows you to only show the month and year picker leaving the day picker hidden.', |
Comment on lines
+41
to
+43
| story: | ||
| 'A Calendar Compat can be modified to set a minDate and maxDate in order to restrict ' + | ||
| 'the dates that can be selected.', |
Comment on lines
+32
to
+34
| story: | ||
| 'A Calendar Compat allows you to pass a callback that returns an array of number that should be' + | ||
| 'marked. This callback provides a starting date and an ending date.', |
Comment on lines
+73
to
+75
| story: | ||
| 'A Calendar Compat allows you to pass a number of days that will be highlighted from the selected date' + | ||
| ' and forward.', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This is PR 2 of 3 in a stack that splits up #36618 ("feat: add non-compat and headless versions for Calendar") into smaller, independently reviewable pieces:
@fluentui/react-calendar-previewpackageCalendarcomponent family inreact-calendar-previewCalendartoreact-headless-components-preview, built on top of this PR's base hooksStack order:
master→calendar-preview-scaffold→calendar-preview-impl→headless-calendar. This PR is based on #36628 and only contains the diff on top of it (component implementation, tests, and stories).What's in this PR
The full
Calendarcomponent family for@fluentui/react-calendar-preview:Calendar,CalendarDay,CalendarMonth,CalendarYear, and their*GridCell/*GridRow/*GridHeaderCell/*GridHeaderRowsubcomponents (hook-based architecture:useX_unstable,renderX_unstable,useXStyles_unstable, plususeXBase_unstable/context-value hooks where the headless layer needs to re-use base state)apps/public-docsite-v9dependency on the new packagePrevious Behavior
Only #36628's empty package scaffold existed.
New Behavior
@fluentui/react-calendar-previewnow exposes a workingCalendarcomponent supporting day/week/work-week/month selection, month and year pickers, keyboard navigation, min/max/restricted dates, and localized formatting — same behavior as in the original PR #36618.Related Issue(s)
Split from #36618.