Skip to content

feat(react-calendar-preview): implement Calendar, month/year pickers, and day grid components - #36629

Open
Dmytro Kirpa (dmytrokirpa) wants to merge 2 commits into
calendar-preview-scaffoldfrom
calendar-preview-impl
Open

feat(react-calendar-preview): implement Calendar, month/year pickers, and day grid components#36629
Dmytro Kirpa (dmytrokirpa) wants to merge 2 commits into
calendar-preview-scaffoldfrom
calendar-preview-impl

Conversation

@dmytrokirpa

@dmytrokirpa Dmytro Kirpa (dmytrokirpa) commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

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:

  1. chore: scaffold react-calendar-preview package #36628 — scaffold the new @fluentui/react-calendar-preview package
  2. feat(react-calendar-preview): implement Calendar, month/year pickers, and day grid components #36629 (this PR) — implement the Calendar component family in react-calendar-preview
  3. feat(react-headless-components-preview): add headless Calendar #36630 — add a headless Calendar to react-headless-components-preview, built on top of this PR's base hooks

Stack order: mastercalendar-preview-scaffoldcalendar-preview-implheadless-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 Calendar component family for @fluentui/react-calendar-preview:

  • Calendar, CalendarDay, CalendarMonth, CalendarYear, and their *GridCell/*GridRow/*GridHeaderCell/*GridHeaderRow subcomponents (hook-based architecture: useX_unstable, renderX_unstable, useXStyles_unstable, plus useXBase_unstable/context-value hooks where the headless layer needs to re-use base state)
  • Shared date-math, date-formatting, and day-grid utilities, plus keyboard/focus/motion hooks
  • Unit tests (Jest), Cypress interaction tests, and Storybook stories/docs
  • apps/public-docsite-v9 dependency on the new package
  • A beachball change file

Previous Behavior

Only #36628's empty package scaffold existed.

New Behavior

@fluentui/react-calendar-preview now exposes a working Calendar component 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.

@github-actions

Copy link
Copy Markdown

Pull request demo site: URL

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.',
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants