Skip to content

[pickers] Remove PickersDay and promote PickerDay2 as a replacement#21739

Open
michelengelen wants to merge 95 commits intomui:masterfrom
michelengelen:bugfix/21615-misaligned-days-in-picker
Open

[pickers] Remove PickersDay and promote PickerDay2 as a replacement#21739
michelengelen wants to merge 95 commits intomui:masterfrom
michelengelen:bugfix/21615-misaligned-days-in-picker

Conversation

@michelengelen
Copy link
Copy Markdown
Member

@michelengelen michelengelen commented Mar 13, 2026

This prevents misalignment when the theme used by the user has a display definition in their typography.caption theme object.

Fixes #21615

Signed-off-by: michel <jsnerdic@gmail.com>
@michelengelen michelengelen self-assigned this Mar 13, 2026
@michelengelen michelengelen added type: bug It doesn't behave as expected. scope: pickers Changes related to the date/time pickers. needs cherry-pick The PR should be cherry-picked to master after merge. v8.x labels Mar 13, 2026
@mui-bot
Copy link
Copy Markdown

mui-bot commented Mar 13, 2026

Deploy preview: https://deploy-preview-21739--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers ▼-3.46KB(-1.50%) ▼-539B(-0.88%)
@mui/x-date-pickers-pro ▼-8.43KB(-2.59%) ▼-1.54KB(-1.85%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against 671bc8e

Copy link
Copy Markdown
Member

@LukasTy LukasTy left a comment

Choose a reason for hiding this comment

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

A couple of additional notes:

  • nitpick: this doesn't look like a pro (DateRangePicker) package change in any way

  • Have you considered the change for PickersDay2 as well?

    • Side note: WDYT, @noraleonte, is that component ready to replace the OG one?
      It's a breaking change, because of styling requirements. So, now, or wait another ~year 🙈
  • Now that I have seen this, I can not unsee it. 🙈
    How come the day number is not vertically aligned within the button? 😂

    Screen.Recording.2026-03-19.at.16.40.40.mov

    @noraleonte, have you noticed this? Do you have a better fix for this than line-height: 1? 🤔

@michelengelen
Copy link
Copy Markdown
Member Author

  • nitpick: this doesn't look like a pro (DateRangePicker) package change in any way

Yes, you are right ... I just took this since it was reported from that component in the bug-issue. Will change that.

  • Have you considered the change for PickersDay2 as well?

No, thanks for pointing me to that though.

  • Side note: WDYT, @noraleonte, is that component ready to replace the OG one?
    It's a breaking change, because of styling requirements. So, now, or wait another ~year 🙈

If possible in any way I would like to include any breaking changes now, ideally with this release. So if there is a decision to be made I would go for it now.

  • Now that I have seen this, I can not unsee it. 🙈
    How come the day number is not vertically aligned within the button? 😂

🫣

@noraleonte, have you noticed this? Do you have a better fix for this than line-height: 1? 🤔

@michelengelen michelengelen changed the title [DateRangePicker] Set display: block for PickersDay component style [PickersDay] Set display: block for PickersDay component style Mar 19, 2026
@michelengelen
Copy link
Copy Markdown
Member Author

michelengelen commented Mar 19, 2026

@noraleonte, have you noticed this? Do you have a better fix for this than line-height: 1? 🤔

@LukasTy I would love to use text-box, but it seems we are a bit early for this, since it is not yet widely adopted

@noraleonte
Copy link
Copy Markdown
Contributor

WDYT, @noraleonte, is that component ready to replace the OG one?
It's a breaking change, because of styling requirements. So, now, or wait another ~year 🙈

I think it might be, but seems a bit short notice to include it in this release 🙈 I'm not worried about the component not being ready, it's more that it's a breaking change, comes with a migration guide + we need to check all the demos are still working properly (customization ones especially) 🙈

@noraleonte, have you noticed this? Do you have a better fix for this than line-height: 1? 🤔

I haven't noticed it but now it's bugging me. Present in PickersDay2 as well btw 🙈 line-height seems to do the job here. Agree with Michel that we should wait a bit for text-box

@LukasTy
Copy link
Copy Markdown
Member

LukasTy commented Mar 20, 2026

So, to conclude, I see two paths:

Lazy

  • Remove change in WeekPicker
  • Set display: flex on PickersDay and PickersDay2
  • Add a migration page entry notifying about the change and urging upgraders to double-check if all is good in their custom implementations (should be fine in at least 99% of cases)

Proper bad-ass 😆

  • Remove change in WeekPicker
  • Remove PickersDay
  • Remove https://mui.com/x/react-date-pickers/custom-components/#day demo
  • Set display: flex on PickersDay2
  • Rename PickersDay2 to PickersDay and DateRangePickerDay2 to DateRangePickerDay
  • Add codemod removing the slots={{ day: PickerDay2 }} and slots={{ day: DateRangePickerDay2 }} usages
  • Add migration guide entry about this component change as well as the display: flex
  • Hope Argos is happy and do some manual testing 👌

In both cases, I'd urge setting line-height: 1 to fix vertical alignment.

Does that sound about right, @noraleonte?

I leave the decision to @michelengelen.

@noraleonte
Copy link
Copy Markdown
Contributor

Yes, that's a pretty accurate summary 👌

michelengelen and others added 7 commits March 20, 2026 14:39
…ponding imports alongside

Signed-off-by: michel <jsnerdic@gmail.com>
…picker' into bugfix/21615-misaligned-days-in-picker
Signed-off-by: michel <jsnerdic@gmail.com>
Signed-off-by: michel <jsnerdic@gmail.com>
Signed-off-by: michel <jsnerdic@gmail.com>
Signed-off-by: michel <jsnerdic@gmail.com>
@michelengelen michelengelen changed the title [PickersDay] Set display: block for PickersDay component style [PickersDay] Remove PickersDay and promote PickerDay2 as a replacement Mar 23, 2026
Signed-off-by: michel <jsnerdic@gmail.com>
Signed-off-by: michel <jsnerdic@gmail.com>
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Mar 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged. and removed PR: out-of-date The pull request has merge conflicts and can't be merged. labels Mar 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Copy link
Copy Markdown
Member

@flaviendelangle flaviendelangle left a comment

Choose a reason for hiding this comment

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

A few remaining points and we are good to go

Code Review: #21739

PR: [PickersDay] Remove PickersDay and promote PickerDay2 as a replacement

Author: Michel Engelen (@michelengelen)
Labels: breaking change, scope: pickers, type: enhancement
Stats: +3,375 / -3,356 across 163 files
Fixes: #21615 (misalignment when theme typography.caption has a display definition)


Rating: 4/5


Overview

This PR consolidates the date picker day components by:

  1. Removing PickersDay (the legacy component with multi-element DOM structure)
  2. Renaming PickerDay2PickerDay (promoting the simplified single-element implementation)
  3. Renaming DateRangePickerDay2DateRangePickerDay (rewriting the range day as a single ButtonBase with pseudo-elements)
  4. Removing disableMargin prop from both components
  5. Providing 5 codemods for automated migration
  6. Comprehensive migration documentation in the v8→v9 guide

Strengths

Excellent migration story

  • 5 separate codemods covering every facet of the breaking change: rename-pickers-day, rename-picker-day-2, remove-picker-day-2, rename-picker-classes, remove-disable-margin
  • Each codemod has actual.spec.tsx / expected.spec.tsx test fixtures and a proper test file
  • The remove-picker-day-2 codemod is particularly thorough — it handles both inline slots={{ day: PickerDay2 }} and variable-based const slots = { day: PickerDay2 } patterns, with dead-code cleanup

Well-documented breaking changes

  • The migration guide clearly explains what changed, why, and how to update for each breaking area (component renames, class renames, disableMargin removal, data-testid changes, selection behavior changes)
  • Code examples are provided for before/after

Simplified DOM structure

  • Moving from multi-element to single-element + pseudo-elements (::before / ::after) is a meaningful improvement for theming and reduces DOM complexity
  • The display: flex + lineHeight: 1 fix directly addresses the reported alignment bug (#21615)

Good test coverage

  • New test for drag events targeting nested day elements, which validates the new single-element structure works with drag-and-drop

Issues & Suggestions

1. Bug in overridesResolver (Medium severity)

In PickerDay.tsx, the overridesResolver has what appears to be a bug carried over from PickerDay2:

ownerState.isDayOutsideMonth && styles.dayOutsideMonth,

The original PickerDay2 had:

!ownerState.isDayOutsideMonth && styles.dayOutsideMonth,

The diff shows this was changed from !ownerState.isDayOutsideMonth to ownerState.isDayOutsideMonth. This looks intentional and correct — the old negation was likely a bug in PickerDay2 since the style should apply when the day is outside the month.

However, confirm this was intentional as the semantic difference is significant.

2. onDaySelect null check added without explanation

// Before
if (!disabled) {
  onDaySelect(day);
}

// After
if (!disabled && onDaySelect) {
  onDaySelect(day);
}

onDaySelect is a required prop in the type definition. Adding a runtime null check for a required prop suggests either:

  • The types should be updated to make it optional, or
  • There's a specific edge case where it can be undefined despite the types

This should be clarified or the types should be aligned.

3. preset-safe codemod ordering

The preset-safe runs all codemods in sequence. The order matters here — rename-picker-day-2 should run before remove-picker-day-2 since the latter looks for PickerDay2 identifiers that may have already been renamed. Verify the execution order is correct.

4. Missing test coverage for PickerDay itself

The PR adds a test for DateRangeCalendar drag behavior with nested elements, but there are no new tests for the renamed/refactored PickerDay component itself (e.g., testing the new firstVisibleCell/lastVisibleCell classes, the filler cell div rendering, or the display: flex fix that motivated this PR).

5. Theme component name backwards compatibility

The theme component name changes from MuiPickersDay to MuiPickerDay and from MuiDateRangePickerDay2 to MuiDateRangePickerDay. Users with theme overrides targeting the old names will silently stop working. The migration docs cover this, but the codemods don't appear to handle theme configuration objects — they focus on imports and JSX usage. Consider documenting this limitation in the codemod section.

6. DateRangePickerDay rewrite is large

The DateRangePickerDay.tsx went from ~250 lines wrapping PickersDay to ~416 lines as a standalone ButtonBase component. While this is architecturally sound (no longer depends on the old PickersDay), the complete rewrite in a single PR makes it harder to review for subtle behavioral regressions. The pseudo-element approach for selection/preview highlighting is well-structured though.


Minor Observations

  • The getDensePickerTheme files correctly update MuiDateRangePickerDay2MuiDateRangePickerDay
  • API page JSON files are properly regenerated
  • Translation files are updated consistently
  • The PickersPlayground component correctly removes PickerDay2/DateRangePickerDay2 references
  • WeekPicker demo properly migrates from PickersDay to PickerDay and removes disableMargin

Summary

A well-executed breaking change with strong migration tooling. The architectural improvement (single-element day components with pseudo-elements) is sound and directly fixes the reported alignment bug. The main areas for improvement are around test coverage for the new PickerDay component and ensuring the codemod execution order is correct in the preset-safe bundle. The migration documentation is thorough and actionable.

@LukasTy LukasTy changed the title [PickersDay] Remove PickersDay and promote PickerDay2 as a replacement [pickers] Remove PickersDay and promote PickerDay2 as a replacement Mar 31, 2026
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Introduces changes that are not backward compatible. scope: pickers Changes related to the date/time pickers. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[question] MuiDateRangePickerDay-day applying display inline which causes the date columns to be misaligned

6 participants