Skip to content

feat(react-headless-components-preview): implement DatePicker (blocked) - #36919

Closed
Dmytro Kirpa (dmytrokirpa) wants to merge 2 commits into
feat/datepicker-publishfrom
feat/datepicker-headless
Closed

Dmytro Kirpa (dmytrokirpa) wants to merge 2 commits into
feat/datepicker-publishfrom
feat/datepicker-headless

Conversation

@dmytrokirpa

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

Copy link
Copy Markdown
Contributor

Previous Behavior

There is no headless DatePicker. The DatePicker base hook supplies date state and popup requests,
but the styled renderer cannot provide an unstyled Input/Calendar integration.

New Behavior

  • Implement stable DatePicker, useDatePicker, renderDatePicker, and related props/slots/state
    and event types through @fluentui/react-headless-components-preview/date-picker.
  • Reuse DatePicker Preview's base state for controlled/uncontrolled dates and visibility, editable
    text, required/boundary/restricted-date validation, formatting/parsing, and callback semantics.
  • Compose headless Input and the pending headless Calendar family. Preserve the native input ref,
    Field associations, consumer cancellation/slot refs, keyboard navigation, and month/year switching.
  • Reuse headless Popover's native modal-dialog lifecycle and CSS-anchor positioning for same-document
    top-layer rendering, inert outside content, dismissal, and focus restoration. No styled fallback,
    default icons, Griffel styles, Portal, or new Tabster behavior is introduced.
  • Reserve Input-wrapper presence attributes data-open, data-disabled, and data-invalid.
    Native dialog state and DatePicker-owned selection/boundaries cannot be overridden by slot props.
  • Add conformance/unit/browser coverage, five CSS Module stories (including initially open hydration),
    public export map/API report, focused/all-components bundle fixtures, and a minor Beachball entry.
  • Narrow the shared data-attribute helper's boolean overload to '' | undefined, without changing
    its runtime behavior.

Dependencies and intentional exclusions

Blocked draft: this is now an implementation, not the former documentation-only placeholder.
It was developed and validated against pending headless Calendar
#36752 (4a32a0ca54dd2709e84ee2cc6343612e64ddfeac) and standalone Calendar
#36917 (ba6a0e9db7).

Those prerequisite sources, stories, exports, generated Calendar API report, and change files are
not committed in this PR. A clean checkout of this stack is not expected to build until the
prerequisites merge and the stack is rebased. Calendar remains outside the DatePicker GitHub stack.
This PR follows public-preview publication #36918; it does not duplicate that PR.

The native dialog intentionally excludes mountNode and inlinePopup. Native dialog/CSS-anchor
support and native focusgroup support (or an application-supplied focusgroup polyfill) are required.
For editable inputs, openOnClick={false} permits typing without opening a modal; the trigger and
Enter/ArrowDown remain available. Callers own styling and visual accessibility.

Validation

All runtime/build evidence below was collected with the exact temporary prerequisites present.
They were removed before committing this PR.

  • NX_DAEMON=false yarn nx run react-headless-components-preview:test --runInBand --runTestsByPath src/components/DatePicker/DatePicker.test.tsx --skipNxCache — passed: 26 tests, including conformance/axe, selection, validation, canceled keyboard/pointer events, controlled requests, disabled state, refs, Field, and server rendering.
  • NX_DAEMON=false yarn nx run react-headless-components-preview:e2e --excludeTaskDependencies --browser chrome --config retries=0 --spec src/components/DatePicker/DatePicker.cy.tsx --skipNxCache — passed: 10 Chrome tests, including focus return/no reopening, native modal inertness, backdrop/Escape, rejected controlled closes, iframe ownership, view switching, month-only selection, editable validation, and RTL.
  • NX_DAEMON=false yarn nx run-many -t type-check -p react-headless-components-preview react-headless-components-preview-stories --excludeTaskDependencies --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-headless-components-preview:lint --command='yarn run -T eslint src/components/DatePicker src/date-picker.ts src/utils/toDataAttributeValue.ts' --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-headless-components-preview-stories:lint --command='yarn run -T eslint src/DatePicker' --skipNxCache — passed.
  • NX_DAEMON=false yarn nx run react-headless-components-preview:build --excludeTaskDependencies --skipNxCache — passed: ESM/CommonJS, declarations, API extraction, and CJS declaration generation.
  • NX_DAEMON=false yarn nx run react-headless-components-preview-stories:build-storybook --excludeTaskDependencies --skipNxCache — passed; existing Storybook asset-size warnings remain.
  • NX_DAEMON=false yarn nx run react-headless-components-preview-stories:test-ssr --command='yarn run -T test-ssr ./src/DatePicker/**/*.stories.tsx' --skipNxCache — passed: all five stories, including an initially open native dialog, SSR and Chrome hydration.
  • NX_DAEMON=false yarn nx run react-headless-components-preview:bundle-size --excludeTaskDependencies --command='yarn run -T monosize measure --fixtures DatePicker.fixture.js --debug' --skipNxCache — passed: 71.616 kB minified, 22.5 kB gzip. Debug bundle inspection found no Griffel/icons/Tabster runtime or styled Calendar/Input implementation.
  • yarn workspace @fluentui/react-headless-components-preview pack --out /Users/dmytrokirpa/.copilot/session-state/c4c94c91-a3cc-4e00-b996-2ff82c856e61/files/react-headless-components-preview.tgz — passed; packed export targets, rewritten workspace ranges, and ESM/CommonJS APIs passed the session smoke script.
  • yarn beachball change --package @fluentui/react-headless-components-preview --scope packages/react-components/react-headless-components-preview/library --since HEAD --no-fetch --no-commit --type minor --message 'Add an unstyled DatePicker with shared date validation, headless Calendar composition, and native modal-dialog behavior.' — passed; package-scoped change file included.
  • Shared Calendar regression validation — 706 Calendar unit tests and 14 styled DatePicker Chrome tests passed; the keyboard callback-order fix is committed only in fix(react-calendar-preview): preserve popup focus and compat geometry #36917.
  • Built Storybook interaction checks — default/controlled selection and close, controlled status updates, editable validation, disabled state, and light/dark surface theming passed.

Manual VoiceOver/NVDA/JAWS checks, full browser/zoom acceptance, and CI visual approval remain
pending. Headless React 17/18 integration runs have not been performed in this change. Nothing
has been merged or published to npm.

Related Issue(s)

…ntegration

Record verified DatePicker base exports, existing headless Input support, the missing headless Calendar dependency, and requirements for the final headless DatePicker layer. Explicitly defer executable API, stories and packaging changes until the public headless Calendar contract is available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compose shared date state with headless Input, pending Calendar, and native modal popup behavior. Keep Calendar prerequisite patches outside the DatePicker stack.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dmytrokirpa Dmytro Kirpa (dmytrokirpa) changed the title docs(react-headless-components-preview): prepare DatePicker integration (blocked) feat(react-headless-components-preview): implement DatePicker (blocked) Oct 18, 2026
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.

1 participant