Skip to content

feat(react-datepicker-preview): implement DatePicker behavior, hooks and stories - #36920

Closed
Dmytro Kirpa (dmytrokirpa) wants to merge 13 commits into
masterfrom
feat/datepicker-implementation
Closed

Dmytro Kirpa (dmytrokirpa) wants to merge 13 commits into
masterfrom
feat/datepicker-implementation

Conversation

@dmytrokirpa

@dmytrokirpa Dmytro Kirpa (dmytrokirpa) commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Previous Behavior

The DatePicker preview branch was behind master calendar changes and failed CI due to:

  • package dependency normalization checks (workspace:^ where * is required),
  • React compiler analyzer/style-state mutation constraints,
  • DatePicker build/type errors against newer Calendar focus-handle signatures.

New Behavior

  • Rebased the DatePicker implementation branch onto current master calendar updates.
  • Normalized DatePicker dependency declarations to satisfy workspace package-dependency policy.
  • Updated DatePicker style hook to return immutable cloned slot state and consume the returned state in DatePicker.tsx, restoring static class names and conformant merge behavior.
  • Synced lockfile/workspace references produced by dependency normalization.

Validation

  • NX_DAEMON=false yarn nx run react-datepicker-preview:build --excludeTaskDependencies --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-datepicker-preview:type-check --excludeTaskDependencies --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-datepicker-preview:lint --excludeTaskDependencies --skipNxCache — passed.
  • yarn nx run react-datepicker-preview:test --runInBand --skipNxCache — passed (111 tests, 1 snapshot).
  • NX_DAEMON=false yarn nx run react-datepicker-preview:react-compiler-analyzer--lint --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-datepicker-preview:test-rit--17--e2e --skipNxCache --parallel=1 — passed (14/14 Cypress tests).
  • NX_DAEMON=false yarn nx run react-datepicker-preview:test-rit--18--e2e --skipNxCache --parallel=1 — passed (14/14 Cypress tests).

Beachball: no change file in this layer — DatePicker preview package remains private.

Related Issue(s)

…icker

<!--
Thank you for submitting a pull request!

Please verify that:
* [ ] Code is up-to-date with the `master` branch
* [ ] Your changes are covered by tests (if possible)
* [ ] You've run `yarn change` locally

PR flow tips:
* [ ] Try to start with a Draft PR
* [ ] Once you're ready (ideally the pipeline is passing) promote your PR to Ready for Review. This step will auto-assign reviewers for your PR.
-->

## Previous Behavior

<!-- This is the behavior we have today -->

DatePicker Compat provides the existing date-input experience. There is no non-compat DatePicker preview package on this branch's base.

## New Behavior

<!-- This is the behavior we should expect with the changes in this PR -->

Adds the private DatePicker preview library and stories scaffold, workspace registration, and ownership entries.

Defines the proposed non-compat DatePicker API and implementation requirements: compat visual/behavioral parity, Calendar Preview composition, v9 slots and event/data callbacks, validation, focus/accessibility, and a compat migration walkthrough.

The scaffold is not a working DatePicker and does not implement the proposed API.

### Planned stack

1. This PR: current scaffold, workspace wiring, spec, and migration guide.
2. Dependent PR: styled DatePicker implementation, shared base hooks suitable for headless reuse, tests, and stories.
3. Dependent PR: headless DatePicker using the base hooks from layer 2, with its integration, tests, and stories.

Layers 2 and 3 are deferred pending resolution of the component-package dependency prerequisite documented in the spec. No new DatePicker-to-Calendar/Input component dependency is introduced here.

### Validation

- `yarn nx run-many -p react-datepicker-preview react-datepicker-preview-stories -t test lint type-check --parallel=3` — passed, including library/story lint and type checks, scaffold tests (20 tests and one snapshot), and dependency builds.
- `git diff --cached --check` — passed before committing.
- Runtime parity, browser interaction, visual regression, and screen-reader validation — not run; the component is still a scaffold.
- Beachball change file — not added: the new library and stories packages are private and this layer changes no published package.

## Related Issue(s)

<!-- Please link the issue being fixed so it gets closed when this is merged. -->

- Fixes # — no linked issue provided.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ation

Implement internal controlled selection, draft editing, parsing, validation, and Calendar range forwarding for subsequent styled and headless integration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nd stories

Implement Input and Calendar composition, validation, popup positioning and dismissal, accessible focus management, SSR-safe portals, public base hooks, API docs, browser and compatibility tests, stories and paired visual fixtures. Keep the package private until its separate release-preparation layer. Depends on the standalone Calendar popup focus and geometry fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the CI label Oct 21, 2026
@dmytrokirpa
Dmytro Kirpa (dmytrokirpa) marked this pull request as ready for review October 21, 2026 05:34
…20-refresh

# Conflicts:
#	.github/CODEOWNERS
#	packages/react-components/react-datepicker-preview/library/README.md
#	packages/react-components/react-datepicker-preview/library/config/tests.cjs
#	packages/react-components/react-datepicker-preview/library/docs/Spec.md
#	packages/react-components/react-datepicker-preview/library/etc/react-datepicker-preview.api.md
#	packages/react-components/react-datepicker-preview/library/package.json
#	packages/react-components/react-datepicker-preview/library/project.json
#	packages/react-components/react-datepicker-preview/library/src/DatePicker.ts
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/DatePicker.test.tsx
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/DatePicker.tsx
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/DatePicker.types.ts
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/index.ts
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/renderDatePicker.tsx
#	packages/react-components/react-datepicker-preview/library/src/components/DatePicker/useDatePickerStyles.styles.ts
#	packages/react-components/react-datepicker-preview/library/src/index.ts
#	packages/react-components/react-datepicker-preview/library/tsconfig.json
#	packages/react-components/react-datepicker-preview/library/tsconfig.lib.json
#	packages/react-components/react-datepicker-preview/stories/src/DatePicker/DatePickerBestPractices.md
#	packages/react-components/react-datepicker-preview/stories/src/DatePicker/DatePickerDefault.stories.tsx
#	packages/react-components/react-datepicker-preview/stories/src/DatePicker/index.stories.tsx
#	tsconfig.base.all.json
#	yarn.lock
@github-actions github-actions Bot removed the CI label Oct 21, 2026
@github-actions

Copy link
Copy Markdown

📊 Bundle size report

✅ No changes found

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.

A few comments to review

@github-actions

Copy link
Copy Markdown

Pull request demo site: URL

Comment thread apps/vr-tests-react-components/package.json

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.

Thanks for working through the earlier comments—all six original cases look addressed. While checking the fixes, I found three related edge cases: opening with an invalid date, continuing to type after the parent declines an opening request, and keeping the requested month on the first opening. I’ve left the examples inline.

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.

🟡 Changes recommended

Unresolved composition-input, wrapper-styling, and controlled-focus defects affect component behavior.

3 open issues
What changed in this PR

Implements the private DatePicker preview scaffold with Input/Calendar composition, reusable behavior hooks, and interaction coverage.

Changes:

  • Adds date selection, text parsing, validation, popup control, and focus management.
  • Adds immutable slot styling, public types, and exports.
  • Expands stories, documentation, unit tests, and browser tests.
File Description
yarn.lock Records new dependencies.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​index.stories.tsx Registers examples.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerWeekNumbers.stories.tsx Demonstrates ISO week numbers.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerTextInput.stories.tsx Demonstrates editable input.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerSizes.stories.tsx Shows size variants.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerRequired.stories.tsx Demonstrates required state.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerPopupOptions.stories.tsx Shows inline positioning.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerLocalized.stories.tsx Demonstrates French localization.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerFirstDayOfTheWeek.stories.tsx Shows Monday-first configuration.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerErrorHandling.stories.tsx Demonstrates validation messages.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDisabled.stories.tsx Shows disabled state.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDescription.md Describes preview capabilities.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDefaultOpenInline.stories.tsx Shows initially open inline popup.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDefaultOpen.stories.tsx Shows initially open popup.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDefault.stories.tsx Adds a labeled default example.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDateRange.stories.tsx Demonstrates week selection.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerDateBoundaries.stories.tsx Demonstrates date restrictions.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerCustomDateFormatting.stories.tsx Shows custom formatting and parsing.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerControlled.stories.tsx Demonstrates controlled state.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerCalendarComposition.stories.tsx Shows Calendar composition options.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerBestPractices.md Adds usage guidance.
packages/​react-components/​react-datepicker-preview/​stories/​src/​DatePicker/​DatePickerAppearance.stories.tsx Shows appearance variants.
packages/​react-components/​react-datepicker-preview/​library/​tsconfig.lib.json Excludes browser tests from builds.
packages/​react-components/​react-datepicker-preview/​library/​tsconfig.json References browser-test configuration.
packages/​react-components/​react-datepicker-preview/​library/​tsconfig.cy.json Configures browser-test types.
packages/​react-components/​react-datepicker-preview/​library/​src/​index.ts Expands package exports.
packages/​react-components/​react-datepicker-preview/​library/​src/​DatePicker.ts Exposes component APIs.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePickerStyles.styles.ts Adds immutable slot styling.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePickerDateState.ts Manages selection and editable drafts.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePickerDateState.test.ts Tests parsing and validation.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePickerBase.ts Shares availability and popup behavior.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePickerBase.test.ts Tests shared behavior.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePicker.tsx Implements composition and interactions.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​useDatePicker.ts Removes the scaffold hook.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​renderDatePicker.tsx Renders input and popup.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​index.ts Exports hooks and types.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​defaults.ts Defines validation messages.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​DatePicker.types.ts Defines the preview API.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​DatePicker.types.test.tsx Checks public type contracts.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​DatePicker.tsx Consumes styled state.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​DatePicker.test.tsx Expands component coverage.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​DatePicker.cy.tsx Adds browser interaction coverage.
packages/​react-components/​react-datepicker-preview/​library/​src/​components/​DatePicker/​__snapshots__/​DatePicker.test.tsx.snap Updates rendered markup expectations.
packages/​react-components/​react-datepicker-preview/​library/​rit.config.js Configures React compatibility tests.
packages/​react-components/​react-datepicker-preview/​library/​README.md Documents usage and release gates.
packages/​react-components/​react-datepicker-preview/​library/​project.json Configures browser-test cache inputs.
packages/​react-components/​react-datepicker-preview/​library/​package.json Adds implementation and test dependencies.
packages/​react-components/​react-datepicker-preview/​library/​etc/​react-datepicker-preview.api.md Updates the API report.
packages/​react-components/​react-datepicker-preview/​library/​docs/​Spec.md Updates implementation status.
packages/​react-components/​react-datepicker-preview/​library/​cypress.config.ts Uses shared Cypress configuration.
packages/​react-components/​react-datepicker-preview/​library/​config/​tests.cjs Enables compatibility-test snapshots.

Review effort: Balanced

const consumerKeyDown = input.onKeyDown ?? root.onKeyDown;
input.onKeyDown = useEventCallback(event => {
consumerKeyDown?.(event);
if (event.defaultPrevented || disabled) {
(findFirstFocusable(surfaceRef.current) ?? surfaceRef.current)?.focus({ preventScroll: true });
}
focusWithinPopup.current = !!surfaceRef.current?.contains(targetDocument?.activeElement ?? null);
} else if (!popupOpen && wasOpen.current && !disabled && (restoreFocus.current ?? focusWithinPopup.current)) {
Comment on lines +61 to +67
className: mergeClasses(
datePickerClassNames.root,
styles.root,
!state.allowTextInput && styles.selectionOnly,
state.disabled && styles.disabled,
state.root.className,
),
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.

3 participants