@mui/x-date-pickers 7.6.2 → 7.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.d.ts +48 -48
  2. package/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  3. package/AdapterDateFnsV3/AdapterDateFnsV3.d.ts +47 -47
  4. package/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  5. package/CHANGELOG.md +163 -0
  6. package/DateCalendar/DateCalendar.js +3 -3
  7. package/DateCalendar/DateCalendar.types.d.ts +4 -4
  8. package/DateCalendar/DayCalendar.d.ts +3 -4
  9. package/DatePicker/DatePicker.js +2 -0
  10. package/DateTimePicker/DateTimePicker.js +2 -0
  11. package/DesktopDatePicker/DesktopDatePicker.js +2 -0
  12. package/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  13. package/DesktopTimePicker/DesktopTimePicker.js +2 -0
  14. package/MobileDatePicker/MobileDatePicker.js +2 -0
  15. package/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  16. package/MobileTimePicker/MobileTimePicker.js +2 -0
  17. package/MonthCalendar/MonthCalendar.js +17 -3
  18. package/MonthCalendar/MonthCalendar.types.d.ts +25 -0
  19. package/MonthCalendar/PickersMonth.d.ts +4 -0
  20. package/MonthCalendar/PickersMonth.js +38 -21
  21. package/MonthCalendar/index.d.ts +1 -1
  22. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  23. package/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  24. package/PickersCalendarHeader/PickersCalendarHeader.types.d.ts +5 -1
  25. package/PickersLayout/usePickerLayout.js +0 -5
  26. package/StaticDatePicker/StaticDatePicker.js +2 -0
  27. package/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  28. package/StaticTimePicker/StaticTimePicker.js +2 -0
  29. package/TimePicker/TimePicker.js +2 -0
  30. package/YearCalendar/PickersYear.d.ts +3 -0
  31. package/YearCalendar/PickersYear.js +34 -22
  32. package/YearCalendar/YearCalendar.js +17 -3
  33. package/YearCalendar/YearCalendar.types.d.ts +25 -0
  34. package/YearCalendar/index.d.ts +1 -1
  35. package/index.js +1 -1
  36. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  37. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.types.d.ts +1 -0
  38. package/internals/hooks/useField/useField.utils.js +2 -1
  39. package/internals/hooks/usePicker/usePickerValue.js +45 -38
  40. package/internals/hooks/usePicker/usePickerValue.types.d.ts +3 -1
  41. package/internals/hooks/usePicker/usePickerViews.js +2 -1
  42. package/locales/daDK.js +15 -19
  43. package/locales/faIR.js +19 -22
  44. package/locales/koKR.js +2 -2
  45. package/modern/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  46. package/modern/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  47. package/modern/DateCalendar/DateCalendar.js +3 -3
  48. package/modern/DatePicker/DatePicker.js +2 -0
  49. package/modern/DateTimePicker/DateTimePicker.js +2 -0
  50. package/modern/DesktopDatePicker/DesktopDatePicker.js +2 -0
  51. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  52. package/modern/DesktopTimePicker/DesktopTimePicker.js +2 -0
  53. package/modern/MobileDatePicker/MobileDatePicker.js +2 -0
  54. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  55. package/modern/MobileTimePicker/MobileTimePicker.js +2 -0
  56. package/modern/MonthCalendar/MonthCalendar.js +17 -3
  57. package/modern/MonthCalendar/PickersMonth.js +38 -21
  58. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  59. package/modern/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  60. package/modern/PickersLayout/usePickerLayout.js +0 -5
  61. package/modern/StaticDatePicker/StaticDatePicker.js +2 -0
  62. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  63. package/modern/StaticTimePicker/StaticTimePicker.js +2 -0
  64. package/modern/TimePicker/TimePicker.js +2 -0
  65. package/modern/YearCalendar/PickersYear.js +34 -22
  66. package/modern/YearCalendar/YearCalendar.js +17 -3
  67. package/modern/index.js +1 -1
  68. package/modern/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  69. package/modern/internals/hooks/useField/useField.utils.js +2 -1
  70. package/modern/internals/hooks/usePicker/usePickerValue.js +45 -38
  71. package/modern/internals/hooks/usePicker/usePickerViews.js +2 -1
  72. package/modern/locales/daDK.js +15 -19
  73. package/modern/locales/faIR.js +19 -22
  74. package/modern/locales/koKR.js +2 -2
  75. package/node/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  76. package/node/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  77. package/node/DateCalendar/DateCalendar.js +3 -3
  78. package/node/DatePicker/DatePicker.js +2 -0
  79. package/node/DateTimePicker/DateTimePicker.js +2 -0
  80. package/node/DesktopDatePicker/DesktopDatePicker.js +2 -0
  81. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  82. package/node/DesktopTimePicker/DesktopTimePicker.js +2 -0
  83. package/node/MobileDatePicker/MobileDatePicker.js +2 -0
  84. package/node/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  85. package/node/MobileTimePicker/MobileTimePicker.js +2 -0
  86. package/node/MonthCalendar/MonthCalendar.js +17 -3
  87. package/node/MonthCalendar/PickersMonth.js +40 -23
  88. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  89. package/node/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  90. package/node/PickersLayout/usePickerLayout.js +0 -5
  91. package/node/StaticDatePicker/StaticDatePicker.js +2 -0
  92. package/node/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  93. package/node/StaticTimePicker/StaticTimePicker.js +2 -0
  94. package/node/TimePicker/TimePicker.js +2 -0
  95. package/node/YearCalendar/PickersYear.js +34 -22
  96. package/node/YearCalendar/YearCalendar.js +17 -3
  97. package/node/index.js +1 -1
  98. package/node/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  99. package/node/internals/hooks/useField/useField.utils.js +2 -1
  100. package/node/internals/hooks/usePicker/usePickerValue.js +45 -38
  101. package/node/internals/hooks/usePicker/usePickerViews.js +2 -1
  102. package/node/locales/daDK.js +15 -19
  103. package/node/locales/faIR.js +19 -22
  104. package/node/locales/koKR.js +2 -2
  105. package/package.json +4 -4
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { PickersMonthClasses } from './pickersMonthClasses';
3
+ import { MonthCalendarSlotProps, MonthCalendarSlots } from './MonthCalendar.types';
3
4
  export interface ExportedPickersMonthProps {
4
5
  classes?: Partial<PickersMonthClasses>;
5
6
  }
@@ -8,6 +9,7 @@ export interface PickersMonthProps extends ExportedPickersMonthProps {
8
9
  'aria-label'?: React.AriaAttributes['aria-label'];
9
10
  autoFocus: boolean;
10
11
  children: React.ReactNode;
12
+ className?: string;
11
13
  disabled?: boolean;
12
14
  onClick: (event: React.MouseEvent, month: number) => void;
13
15
  onKeyDown: (event: React.KeyboardEvent, month: number) => void;
@@ -17,6 +19,8 @@ export interface PickersMonthProps extends ExportedPickersMonthProps {
17
19
  value: number;
18
20
  tabIndex: number;
19
21
  monthsPerRow: 3 | 4;
22
+ slots?: MonthCalendarSlots;
23
+ slotProps?: MonthCalendarSlotProps;
20
24
  }
21
25
  /**
22
26
  * @ignore - do not document.
@@ -1,9 +1,12 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "aria-label", "monthsPerRow"];
3
+ const _excluded = ["autoFocus", "className", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "aria-label", "monthsPerRow", "slots", "slotProps"];
4
4
  import * as React from 'react';
5
+ import clsx from 'clsx';
5
6
  import { styled, alpha, useThemeProps } from '@mui/material/styles';
6
- import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
7
+ import { useSlotProps } from '@mui/base/utils';
8
+ import composeClasses from '@mui/utils/composeClasses';
9
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
7
10
  import { getPickersMonthUtilityClass, pickersMonthClasses } from './pickersMonthClasses';
8
11
  import { jsx as _jsx } from "react/jsx-runtime";
9
12
  const useUtilityClasses = ownerState => {
@@ -36,7 +39,7 @@ const PickersMonthRoot = styled('div', {
36
39
  }
37
40
  }]
38
41
  });
39
- const PickersMonthButton = styled('button', {
42
+ const MonthCalendarButton = styled('button', {
40
43
  name: 'MuiPickersMonth',
41
44
  slot: 'MonthButton',
42
45
  overridesResolver: (_, styles) => [styles.monthButton, {
@@ -89,6 +92,7 @@ export const PickersMonth = /*#__PURE__*/React.memo(function PickersMonth(inProp
89
92
  });
90
93
  const {
91
94
  autoFocus,
95
+ className,
92
96
  children,
93
97
  disabled,
94
98
  selected,
@@ -101,35 +105,48 @@ export const PickersMonth = /*#__PURE__*/React.memo(function PickersMonth(inProp
101
105
  'aria-current': ariaCurrent,
102
106
  'aria-label': ariaLabel
103
107
  // We don't want to forward this prop to the root element
108
+ ,
109
+
110
+ slots,
111
+ slotProps
104
112
  } = props,
105
113
  other = _objectWithoutPropertiesLoose(props, _excluded);
106
114
  const ref = React.useRef(null);
107
115
  const classes = useUtilityClasses(props);
116
+
117
+ // We can't forward the `autoFocus` to the button because it is a native button, not a MUI Button
108
118
  useEnhancedEffect(() => {
109
119
  if (autoFocus) {
120
+ // `ref.current` being `null` would be a bug in MUI.
110
121
  ref.current?.focus();
111
122
  }
112
123
  }, [autoFocus]);
113
- return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({
114
- className: classes.root,
115
- ownerState: props
116
- }, other, {
117
- children: /*#__PURE__*/_jsx(PickersMonthButton, {
118
- ref: ref,
119
- disabled: disabled,
120
- type: "button",
121
- role: "radio",
122
- tabIndex: disabled ? -1 : tabIndex,
123
- "aria-current": ariaCurrent,
124
- "aria-checked": selected,
125
- "aria-label": ariaLabel,
124
+ const MonthButton = slots?.monthButton ?? MonthCalendarButton;
125
+ const monthButtonProps = useSlotProps({
126
+ elementType: MonthButton,
127
+ externalSlotProps: slotProps?.monthButton,
128
+ additionalProps: {
129
+ children,
130
+ disabled,
131
+ tabIndex,
132
+ ref,
133
+ type: 'button',
134
+ role: 'radio',
135
+ 'aria-current': ariaCurrent,
136
+ 'aria-checked': selected,
137
+ 'aria-label': ariaLabel,
126
138
  onClick: event => onClick(event, value),
127
139
  onKeyDown: event => onKeyDown(event, value),
128
140
  onFocus: event => onFocus(event, value),
129
- onBlur: event => onBlur(event, value),
130
- className: classes.monthButton,
131
- ownerState: props,
132
- children: children
133
- })
141
+ onBlur: event => onBlur(event, value)
142
+ },
143
+ ownerState: props,
144
+ className: classes.monthButton
145
+ });
146
+ return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({
147
+ className: clsx(classes.root, className),
148
+ ownerState: props
149
+ }, other, {
150
+ children: /*#__PURE__*/_jsx(MonthButton, _extends({}, monthButtonProps))
134
151
  }));
135
152
  });
@@ -1,5 +1,5 @@
1
1
  export { MonthCalendar } from './MonthCalendar';
2
- export type { MonthCalendarProps } from './MonthCalendar.types';
2
+ export type { MonthCalendarProps, MonthCalendarSlots, MonthCalendarSlotProps, } from './MonthCalendar.types';
3
3
  export { monthCalendarClasses, getMonthCalendarUtilityClass } from './monthCalendarClasses';
4
4
  export type { MonthCalendarClasses, MonthCalendarClassKey } from './monthCalendarClasses';
5
5
  export { pickersMonthClasses } from './pickersMonthClasses';
@@ -4,6 +4,7 @@ const _excluded = ["ampm", "timeSteps", "autoFocus", "slots", "slotProps", "valu
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
6
  import PropTypes from 'prop-types';
7
+ import { useRtl } from '@mui/system/RtlProvider';
7
8
  import { styled, useThemeProps } from '@mui/material/styles';
8
9
  import useEventCallback from '@mui/utils/useEventCallback';
9
10
  import composeClasses from '@mui/utils/composeClasses';
@@ -53,6 +54,7 @@ const MultiSectionDigitalClockRoot = styled(PickerViewRoot, {
53
54
  */
54
55
  export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function MultiSectionDigitalClock(inProps, ref) {
55
56
  const utils = useUtils();
57
+ const isRtl = useRtl();
56
58
  const props = useThemeProps({
57
59
  props: inProps,
58
60
  name: 'MuiMultiSectionDigitalClock'
@@ -295,6 +297,17 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
295
297
  throw new Error(`Unknown view: ${viewToBuild} found.`);
296
298
  }
297
299
  }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, isTimeDisabled, handleMeridiemChange]);
300
+ const viewsToRender = React.useMemo(() => {
301
+ if (!isRtl) {
302
+ return views;
303
+ }
304
+ const digitViews = views.filter(v => v !== 'meridiem');
305
+ const result = digitViews.toReversed();
306
+ if (views.includes('meridiem')) {
307
+ result.push('meridiem');
308
+ }
309
+ return result;
310
+ }, [isRtl, views]);
298
311
  const viewTimeOptions = React.useMemo(() => {
299
312
  return views.reduce((result, currentView) => {
300
313
  return _extends({}, result, {
@@ -310,9 +323,9 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
310
323
  ownerState: ownerState,
311
324
  role: "group"
312
325
  }, other, {
313
- children: Object.entries(viewTimeOptions).map(([timeView, viewOptions]) => /*#__PURE__*/_jsx(MultiSectionDigitalClockSection, {
314
- items: viewOptions.items,
315
- onChange: viewOptions.onChange,
326
+ children: viewsToRender.map(timeView => /*#__PURE__*/_jsx(MultiSectionDigitalClockSection, {
327
+ items: viewTimeOptions[timeView].items,
328
+ onChange: viewTimeOptions[timeView].onChange,
316
329
  active: view === timeView,
317
330
  autoFocus: autoFocus ?? focusedView === timeView,
318
331
  disabled: disabled,
@@ -243,6 +243,10 @@ process.env.NODE_ENV !== "production" ? PickersCalendarHeader.propTypes = {
243
243
  * @default `${adapter.formats.month} ${adapter.formats.year}`
244
244
  */
245
245
  format: PropTypes.string,
246
+ /**
247
+ * Id of the calendar text element.
248
+ * It is used to establish an `aria-labelledby` relationship with the calendar `grid` element.
249
+ */
246
250
  labelId: PropTypes.string,
247
251
  maxDate: PropTypes.object.isRequired,
248
252
  minDate: PropTypes.object.isRequired,
@@ -15,7 +15,7 @@ export interface PickersCalendarHeaderSlots extends PickersArrowSwitcherSlots {
15
15
  */
16
16
  switchViewButton?: React.ElementType;
17
17
  /**
18
- * Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is 'year'.
18
+ * Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is "year".
19
19
  * @default ArrowDropDown
20
20
  */
21
21
  switchViewIcon?: React.ElementType;
@@ -45,6 +45,10 @@ export interface PickersCalendarHeaderProps<TDate extends PickerValidDate> exten
45
45
  view: DateView;
46
46
  reduceAnimations: boolean;
47
47
  onViewChange?: (view: DateView) => void;
48
+ /**
49
+ * Id of the calendar text element.
50
+ * It is used to establish an `aria-labelledby` relationship with the calendar `grid` element.
51
+ */
48
52
  labelId?: string;
49
53
  /**
50
54
  * Override or extend the styles applied to the component.
@@ -53,7 +53,6 @@ const usePickerLayout = props => {
53
53
  const classes = useUtilityClasses(props);
54
54
 
55
55
  // Action bar
56
-
57
56
  const ActionBar = slots?.actionBar ?? PickersActionBar;
58
57
  const actionBarProps = useSlotProps({
59
58
  elementType: ActionBar,
@@ -73,7 +72,6 @@ const usePickerLayout = props => {
73
72
  const actionBar = /*#__PURE__*/_jsx(ActionBar, _extends({}, actionBarProps));
74
73
 
75
74
  // Toolbar
76
-
77
75
  const Toolbar = slots?.toolbar;
78
76
  const toolbarProps = useSlotProps({
79
77
  elementType: Toolbar,
@@ -96,11 +94,9 @@ const usePickerLayout = props => {
96
94
  const toolbar = toolbarHasView(toolbarProps) && !!Toolbar ? /*#__PURE__*/_jsx(Toolbar, _extends({}, toolbarProps)) : null;
97
95
 
98
96
  // Content
99
-
100
97
  const content = children;
101
98
 
102
99
  // Tabs
103
-
104
100
  const Tabs = slots?.tabs;
105
101
  const tabs = view && Tabs ? /*#__PURE__*/_jsx(Tabs, _extends({
106
102
  view: view,
@@ -109,7 +105,6 @@ const usePickerLayout = props => {
109
105
  }, slotProps?.tabs)) : null;
110
106
 
111
107
  // Shortcuts
112
-
113
108
  const Shortcuts = slots?.shortcuts ?? PickersShortcuts;
114
109
  const shortcutsProps = useSlotProps({
115
110
  elementType: Shortcuts,
@@ -133,7 +133,9 @@ StaticDatePicker.propTypes = {
133
133
  /**
134
134
  * Callback fired when the value is accepted.
135
135
  * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
136
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
136
137
  * @param {TValue} value The value that was just accepted.
138
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
137
139
  */
138
140
  onAccept: PropTypes.func,
139
141
  /**
@@ -181,7 +181,9 @@ StaticDateTimePicker.propTypes = {
181
181
  /**
182
182
  * Callback fired when the value is accepted.
183
183
  * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
184
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
184
185
  * @param {TValue} value The value that was just accepted.
186
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
185
187
  */
186
188
  onAccept: PropTypes.func,
187
189
  /**
@@ -125,7 +125,9 @@ StaticTimePicker.propTypes = {
125
125
  /**
126
126
  * Callback fired when the value is accepted.
127
127
  * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
128
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
128
129
  * @param {TValue} value The value that was just accepted.
130
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
129
131
  */
130
132
  onAccept: PropTypes.func,
131
133
  /**
@@ -157,7 +157,9 @@ process.env.NODE_ENV !== "production" ? TimePicker.propTypes = {
157
157
  /**
158
158
  * Callback fired when the value is accepted.
159
159
  * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
160
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
160
161
  * @param {TValue} value The value that was just accepted.
162
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
161
163
  */
162
164
  onAccept: PropTypes.func,
163
165
  /**
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { PickersYearClasses } from './pickersYearClasses';
3
+ import { YearCalendarSlotProps, YearCalendarSlots } from './YearCalendar.types';
3
4
  export interface ExportedPickersYearProps {
4
5
  classes?: Partial<PickersYearClasses>;
5
6
  }
@@ -17,6 +18,8 @@ export interface PickersYearProps extends ExportedPickersYearProps {
17
18
  value: number;
18
19
  tabIndex: number;
19
20
  yearsPerRow: 3 | 4;
21
+ slots?: YearCalendarSlots;
22
+ slotProps?: YearCalendarSlotProps;
20
23
  }
21
24
  /**
22
25
  * @ignore - internal component.
@@ -1,10 +1,12 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "className", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "yearsPerRow"];
3
+ const _excluded = ["autoFocus", "className", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "yearsPerRow", "slots", "slotProps"];
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
- import { unstable_composeClasses as composeClasses } from '@mui/utils';
7
- import { alpha, styled, useThemeProps } from '@mui/material/styles';
6
+ import { styled, alpha, useThemeProps } from '@mui/material/styles';
7
+ import { useSlotProps } from '@mui/base/utils';
8
+ import composeClasses from '@mui/utils/composeClasses';
9
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
8
10
  import { getPickersYearUtilityClass, pickersYearClasses } from './pickersYearClasses';
9
11
  import { jsx as _jsx } from "react/jsx-runtime";
10
12
  const useUtilityClasses = ownerState => {
@@ -37,7 +39,7 @@ const PickersYearRoot = styled('div', {
37
39
  }
38
40
  }]
39
41
  });
40
- const PickersYearButton = styled('button', {
42
+ const YearCalendarButton = styled('button', {
41
43
  name: 'MuiPickersYear',
42
44
  slot: 'YearButton',
43
45
  overridesResolver: (_, styles) => [styles.yearButton, {
@@ -102,37 +104,47 @@ export const PickersYear = /*#__PURE__*/React.memo(function PickersYear(inProps)
102
104
  onBlur,
103
105
  'aria-current': ariaCurrent
104
106
  // We don't want to forward this prop to the root element
107
+ ,
108
+
109
+ slots,
110
+ slotProps
105
111
  } = props,
106
112
  other = _objectWithoutPropertiesLoose(props, _excluded);
107
113
  const ref = React.useRef(null);
108
114
  const classes = useUtilityClasses(props);
109
115
 
110
116
  // We can't forward the `autoFocus` to the button because it is a native button, not a MUI Button
111
- React.useEffect(() => {
117
+ useEnhancedEffect(() => {
112
118
  if (autoFocus) {
113
119
  // `ref.current` being `null` would be a bug in MUI.
114
- ref.current.focus();
120
+ ref.current?.focus();
115
121
  }
116
122
  }, [autoFocus]);
123
+ const YearButton = slots?.yearButton ?? YearCalendarButton;
124
+ const yearButtonProps = useSlotProps({
125
+ elementType: YearButton,
126
+ externalSlotProps: slotProps?.yearButton,
127
+ additionalProps: {
128
+ children,
129
+ disabled,
130
+ tabIndex,
131
+ ref,
132
+ type: 'button',
133
+ role: 'radio',
134
+ 'aria-current': ariaCurrent,
135
+ 'aria-checked': selected,
136
+ onClick: event => onClick(event, value),
137
+ onKeyDown: event => onKeyDown(event, value),
138
+ onFocus: event => onFocus(event, value),
139
+ onBlur: event => onBlur(event, value)
140
+ },
141
+ ownerState: props,
142
+ className: classes.yearButton
143
+ });
117
144
  return /*#__PURE__*/_jsx(PickersYearRoot, _extends({
118
145
  className: clsx(classes.root, className),
119
146
  ownerState: props
120
147
  }, other, {
121
- children: /*#__PURE__*/_jsx(PickersYearButton, {
122
- ref: ref,
123
- disabled: disabled,
124
- type: "button",
125
- role: "radio",
126
- tabIndex: disabled ? -1 : tabIndex,
127
- "aria-current": ariaCurrent,
128
- "aria-checked": selected,
129
- onClick: event => onClick(event, value),
130
- onKeyDown: event => onKeyDown(event, value),
131
- onFocus: event => onFocus(event, value),
132
- onBlur: event => onBlur(event, value),
133
- className: classes.yearButton,
134
- ownerState: props,
135
- children: children
136
- })
148
+ children: /*#__PURE__*/_jsx(YearButton, _extends({}, yearButtonProps))
137
149
  }));
138
150
  });
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "className", "value", "defaultValue", "referenceDate", "disabled", "disableFuture", "disablePast", "maxDate", "minDate", "onChange", "readOnly", "shouldDisableYear", "disableHighlightToday", "onYearFocus", "hasFocus", "onFocusedViewChange", "yearsPerRow", "timezone", "gridLabelId"];
3
+ const _excluded = ["autoFocus", "className", "value", "defaultValue", "referenceDate", "disabled", "disableFuture", "disablePast", "maxDate", "minDate", "onChange", "readOnly", "shouldDisableYear", "disableHighlightToday", "onYearFocus", "hasFocus", "onFocusedViewChange", "yearsPerRow", "timezone", "gridLabelId", "slots", "slotProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
@@ -88,7 +88,9 @@ export const YearCalendar = /*#__PURE__*/React.forwardRef(function YearCalendar(
88
88
  onFocusedViewChange,
89
89
  yearsPerRow,
90
90
  timezone: timezoneProp,
91
- gridLabelId
91
+ gridLabelId,
92
+ slots,
93
+ slotProps
92
94
  } = props,
93
95
  other = _objectWithoutPropertiesLoose(props, _excluded);
94
96
  const {
@@ -244,11 +246,13 @@ export const YearCalendar = /*#__PURE__*/React.forwardRef(function YearCalendar(
244
246
  onKeyDown: handleKeyDown,
245
247
  autoFocus: internalHasFocus && yearNumber === focusedYear,
246
248
  disabled: isDisabled,
247
- tabIndex: yearNumber === focusedYear ? 0 : -1,
249
+ tabIndex: yearNumber === focusedYear && !isDisabled ? 0 : -1,
248
250
  onFocus: handleYearFocus,
249
251
  onBlur: handleYearBlur,
250
252
  "aria-current": todayYear === yearNumber ? 'date' : undefined,
251
253
  yearsPerRow: yearsPerRow,
254
+ slots: slots,
255
+ slotProps: slotProps,
252
256
  children: utils.format(year, 'year')
253
257
  }, utils.format(year, 'year'));
254
258
  })
@@ -323,6 +327,16 @@ process.env.NODE_ENV !== "production" ? YearCalendar.propTypes = {
323
327
  * @returns {boolean} If `true`, the year will be disabled.
324
328
  */
325
329
  shouldDisableYear: PropTypes.func,
330
+ /**
331
+ * The props used for each component slot.
332
+ * @default {}
333
+ */
334
+ slotProps: PropTypes.object,
335
+ /**
336
+ * Overridable component slots.
337
+ * @default {}
338
+ */
339
+ slots: PropTypes.object,
326
340
  /**
327
341
  * The system prop that allows defining system overrides as well as additional CSS styles.
328
342
  */
@@ -1,8 +1,23 @@
1
+ import * as React from 'react';
1
2
  import { SxProps } from '@mui/system';
2
3
  import { Theme } from '@mui/material/styles';
3
4
  import { YearCalendarClasses } from './yearCalendarClasses';
4
5
  import { BaseDateValidationProps, YearValidationProps } from '../internals/models/validation';
5
6
  import { PickerValidDate, TimezoneProps } from '../models';
7
+ import type { PickersYearProps } from './PickersYear';
8
+ import { SlotComponentPropsFromProps } from '../internals/models/helpers';
9
+ export interface YearCalendarSlots {
10
+ /**
11
+ * Button displayed to render a single year in the "year" view.
12
+ * @default YearCalendarButton
13
+ */
14
+ yearButton?: React.ElementType;
15
+ }
16
+ export interface YearCalendarSlotProps {
17
+ yearButton?: SlotComponentPropsFromProps<React.HTMLAttributes<HTMLButtonElement> & {
18
+ sx: SxProps;
19
+ }, {}, PickersYearProps>;
20
+ }
6
21
  export interface ExportedYearCalendarProps {
7
22
  /**
8
23
  * Years rendered per row.
@@ -17,6 +32,16 @@ export interface YearCalendarProps<TDate extends PickerValidDate> extends Export
17
32
  * Override or extend the styles applied to the component.
18
33
  */
19
34
  classes?: Partial<YearCalendarClasses>;
35
+ /**
36
+ * Overridable component slots.
37
+ * @default {}
38
+ */
39
+ slots?: YearCalendarSlots;
40
+ /**
41
+ * The props used for each component slot.
42
+ * @default {}
43
+ */
44
+ slotProps?: YearCalendarSlotProps;
20
45
  /**
21
46
  * The system prop that allows defining system overrides as well as additional CSS styles.
22
47
  */
@@ -1,5 +1,5 @@
1
1
  export { YearCalendar } from './YearCalendar';
2
- export type { YearCalendarProps } from './YearCalendar.types';
2
+ export type { YearCalendarProps, YearCalendarSlots, YearCalendarSlotProps, } from './YearCalendar.types';
3
3
  export { yearCalendarClasses, getYearCalendarUtilityClass } from './yearCalendarClasses';
4
4
  export type { YearCalendarClasses, YearCalendarClassKey } from './yearCalendarClasses';
5
5
  export { pickersYearClasses } from './pickersYearClasses';
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.6.2
2
+ * @mui/x-date-pickers v7.7.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["children", "className", "slots", "slotProps", "isNextDisabled", "isNextHidden", "onGoToNext", "nextLabel", "isPreviousDisabled", "isPreviousHidden", "onGoToPrevious", "previousLabel"],
3
+ const _excluded = ["children", "className", "slots", "slotProps", "isNextDisabled", "isNextHidden", "onGoToNext", "nextLabel", "isPreviousDisabled", "isPreviousHidden", "onGoToPrevious", "previousLabel", "labelId"],
4
4
  _excluded2 = ["ownerState"],
5
5
  _excluded3 = ["ownerState"];
6
6
  import * as React from 'react';
@@ -73,7 +73,8 @@ export const PickersArrowSwitcher = /*#__PURE__*/React.forwardRef(function Picke
73
73
  isPreviousDisabled,
74
74
  isPreviousHidden,
75
75
  onGoToPrevious,
76
- previousLabel
76
+ previousLabel,
77
+ labelId
77
78
  } = props,
78
79
  other = _objectWithoutPropertiesLoose(props, _excluded);
79
80
  const ownerState = props;
@@ -156,6 +157,7 @@ export const PickersArrowSwitcher = /*#__PURE__*/React.forwardRef(function Picke
156
157
  })), children ? /*#__PURE__*/_jsx(Typography, {
157
158
  variant: "subtitle1",
158
159
  component: "span",
160
+ id: labelId,
159
161
  children: children
160
162
  }) : /*#__PURE__*/_jsx(PickersArrowSwitcherSpacer, {
161
163
  className: classes.spacer,
@@ -34,6 +34,7 @@ export interface PickersArrowSwitcherProps extends ExportedPickersArrowSwitcherP
34
34
  isNextHidden?: boolean;
35
35
  onGoToNext: () => void;
36
36
  nextLabel: string;
37
+ labelId?: string;
37
38
  }
38
39
  export type PickersArrowSwitcherOwnerState = PickersArrowSwitcherProps;
39
40
  export interface PickersArrowSwitcherSlotPropsOverrides {
@@ -103,7 +103,8 @@ export const applyLocalizedDigits = (valueStr, localizedDigits) => {
103
103
  };
104
104
  export const isStringNumber = (valueStr, localizedDigits) => {
105
105
  const nonLocalizedValueStr = removeLocalizedDigits(valueStr, localizedDigits);
106
- return !Number.isNaN(Number(nonLocalizedValueStr));
106
+ // `Number(' ')` returns `0` even if ' ' is not a valid number.
107
+ return nonLocalizedValueStr !== ' ' && !Number.isNaN(Number(nonLocalizedValueStr));
107
108
  };
108
109
 
109
110
  /**