@mui/x-date-pickers 9.0.2 → 9.0.4

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 (40) hide show
  1. package/AdapterDateFnsBase/AdapterDateFnsBase.js +14 -0
  2. package/AdapterDateFnsBase/AdapterDateFnsBase.mjs +14 -0
  3. package/AdapterDayjs/AdapterDayjs.js +1 -13
  4. package/AdapterDayjs/AdapterDayjs.mjs +1 -13
  5. package/AdapterMoment/AdapterMoment.js +6 -0
  6. package/AdapterMoment/AdapterMoment.mjs +6 -0
  7. package/CHANGELOG.md +223 -0
  8. package/PickersLayout/PickersLayout.js +12 -7
  9. package/PickersLayout/PickersLayout.mjs +12 -7
  10. package/PickersLayout/PickersLayout.types.d.mts +1 -1
  11. package/PickersLayout/PickersLayout.types.d.ts +1 -1
  12. package/PickersTextField/PickersFilledInput/PickersFilledInput.js +2 -2
  13. package/PickersTextField/PickersFilledInput/PickersFilledInput.mjs +2 -2
  14. package/PickersTextField/PickersInput/PickersInput.js +2 -2
  15. package/PickersTextField/PickersInput/PickersInput.mjs +2 -2
  16. package/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.js +3 -3
  17. package/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.mjs +3 -3
  18. package/index.js +1 -1
  19. package/index.mjs +1 -1
  20. package/internals/components/PickerPopper/PickerPopper.js +1 -1
  21. package/internals/components/PickerPopper/PickerPopper.mjs +1 -1
  22. package/internals/hooks/useDesktopPicker/useDesktopPicker.js +2 -0
  23. package/internals/hooks/useDesktopPicker/useDesktopPicker.mjs +2 -0
  24. package/internals/hooks/useField/useField.utils.js +22 -2
  25. package/internals/hooks/useField/useField.utils.mjs +22 -2
  26. package/internals/hooks/useField/useFieldRootProps.js +1 -1
  27. package/internals/hooks/useField/useFieldRootProps.mjs +1 -1
  28. package/internals/hooks/useMobilePicker/useMobilePicker.js +2 -0
  29. package/internals/hooks/useMobilePicker/useMobilePicker.mjs +2 -0
  30. package/internals/hooks/useStaticPicker/useStaticPicker.js +1 -1
  31. package/internals/hooks/useStaticPicker/useStaticPicker.mjs +2 -2
  32. package/internals/index.d.mts +1 -1
  33. package/internals/index.d.ts +1 -1
  34. package/internals/index.js +6 -0
  35. package/internals/index.mjs +1 -1
  36. package/internals/utils/utils.d.mts +6 -0
  37. package/internals/utils/utils.d.ts +6 -0
  38. package/internals/utils/utils.js +18 -1
  39. package/internals/utils/utils.mjs +15 -0
  40. package/package.json +123 -123
@@ -306,13 +306,33 @@ const getSectionsBoundaries = (adapter, localizedDigits, timezone) => {
306
306
  format
307
307
  }) => {
308
308
  const lastHourInDay = adapter.getHours(endOfDay);
309
- const hasMeridiem = removeLocalizedDigits(adapter.formatByString(adapter.endOfDay(today), format), localizedDigits) !== lastHourInDay.toString();
309
+ const formattedMidnight = Number(removeLocalizedDigits(adapter.formatByString(adapter.startOfDay(today), format), localizedDigits));
310
+ const formattedEndOfDay = Number(removeLocalizedDigits(adapter.formatByString(adapter.endOfDay(today), format), localizedDigits));
311
+ const hasMeridiem = formattedEndOfDay !== lastHourInDay;
310
312
  if (hasMeridiem) {
313
+ // K/KK format (hour 0-11): midnight formats as 0
314
+ if (formattedMidnight === 0) {
315
+ return {
316
+ minimum: 0,
317
+ maximum: formattedEndOfDay
318
+ };
319
+ }
320
+ // h/hh format (hour 1-12): midnight formats as 12
311
321
  return {
312
322
  minimum: 1,
313
- maximum: Number(removeLocalizedDigits(adapter.formatByString(adapter.startOfDay(today), format), localizedDigits))
323
+ maximum: formattedMidnight
314
324
  };
315
325
  }
326
+
327
+ // k/kk format (hour 1-24): midnight formats as 24 (> lastHourInDay)
328
+ if (formattedMidnight > lastHourInDay) {
329
+ return {
330
+ minimum: 1,
331
+ maximum: formattedMidnight
332
+ };
333
+ }
334
+
335
+ // H/HH format (hour 0-23)
316
336
  return {
317
337
  minimum: 0,
318
338
  maximum: lastHourInDay
@@ -285,13 +285,33 @@ export const getSectionsBoundaries = (adapter, localizedDigits, timezone) => {
285
285
  format
286
286
  }) => {
287
287
  const lastHourInDay = adapter.getHours(endOfDay);
288
- const hasMeridiem = removeLocalizedDigits(adapter.formatByString(adapter.endOfDay(today), format), localizedDigits) !== lastHourInDay.toString();
288
+ const formattedMidnight = Number(removeLocalizedDigits(adapter.formatByString(adapter.startOfDay(today), format), localizedDigits));
289
+ const formattedEndOfDay = Number(removeLocalizedDigits(adapter.formatByString(adapter.endOfDay(today), format), localizedDigits));
290
+ const hasMeridiem = formattedEndOfDay !== lastHourInDay;
289
291
  if (hasMeridiem) {
292
+ // K/KK format (hour 0-11): midnight formats as 0
293
+ if (formattedMidnight === 0) {
294
+ return {
295
+ minimum: 0,
296
+ maximum: formattedEndOfDay
297
+ };
298
+ }
299
+ // h/hh format (hour 1-12): midnight formats as 12
290
300
  return {
291
301
  minimum: 1,
292
- maximum: Number(removeLocalizedDigits(adapter.formatByString(adapter.startOfDay(today), format), localizedDigits))
302
+ maximum: formattedMidnight
293
303
  };
294
304
  }
305
+
306
+ // k/kk format (hour 1-24): midnight formats as 24 (> lastHourInDay)
307
+ if (formattedMidnight > lastHourInDay) {
308
+ return {
309
+ minimum: 1,
310
+ maximum: formattedMidnight
311
+ };
312
+ }
313
+
314
+ // H/HH format (hour 0-23)
295
315
  return {
296
316
  minimum: 0,
297
317
  maximum: lastHourInDay
@@ -60,7 +60,7 @@ function useFieldRootProps(parameters) {
60
60
  // eslint-disable-next-line default-case
61
61
  switch (true) {
62
62
  // Select all
63
- case (event.ctrlKey || event.metaKey) && String.fromCharCode(event.keyCode) === 'A' && !event.shiftKey && !event.altKey:
63
+ case (event.ctrlKey || event.metaKey) && (event.key?.toUpperCase() === 'A' || String.fromCharCode(event.keyCode) === 'A') && !event.shiftKey && !event.altKey:
64
64
  {
65
65
  // prevent default to make sure that the next line "select all" while updating
66
66
  // the internal state at the same time.
@@ -54,7 +54,7 @@ export function useFieldRootProps(parameters) {
54
54
  // eslint-disable-next-line default-case
55
55
  switch (true) {
56
56
  // Select all
57
- case (event.ctrlKey || event.metaKey) && String.fromCharCode(event.keyCode) === 'A' && !event.shiftKey && !event.altKey:
57
+ case (event.ctrlKey || event.metaKey) && (event.key?.toUpperCase() === 'A' || String.fromCharCode(event.keyCode) === 'A') && !event.shiftKey && !event.altKey:
58
58
  {
59
59
  // prevent default to make sure that the next line "select all" while updating
60
60
  // the internal state at the same time.
@@ -13,6 +13,7 @@ var _usePicker = require("../usePicker");
13
13
  var _PickersLayout = require("../../../PickersLayout");
14
14
  var _PickerProvider = require("../../components/PickerProvider");
15
15
  var _createNonRangePickerStepNavigation = require("../../utils/createNonRangePickerStepNavigation");
16
+ var _utils = require("../../utils/utils");
16
17
  var _jsxRuntime = require("react/jsx-runtime");
17
18
  const _excluded = ["props", "steps"],
18
19
  _excluded2 = ["ownerState"];
@@ -56,6 +57,7 @@ const useMobilePicker = _ref => {
56
57
  const _useSlotProps = (0, _useSlotProps2.default)({
57
58
  elementType: Field,
58
59
  externalSlotProps: innerSlotProps?.field,
60
+ externalForwardedProps: (0, _utils.extractRootForwardedProps)(props),
59
61
  additionalProps: (0, _extends2.default)({}, isToolbarHidden && {
60
62
  id: labelId
61
63
  }),
@@ -8,6 +8,7 @@ import { usePicker } from "../usePicker/index.mjs";
8
8
  import { PickersLayout } from "../../../PickersLayout/index.mjs";
9
9
  import { PickerProvider } from "../../components/PickerProvider.mjs";
10
10
  import { createNonRangePickerStepNavigation } from "../../utils/createNonRangePickerStepNavigation.mjs";
11
+ import { extractRootForwardedProps } from "../../utils/utils.mjs";
11
12
 
12
13
  /**
13
14
  * Hook managing all the single-date mobile pickers:
@@ -50,6 +51,7 @@ export const useMobilePicker = _ref => {
50
51
  const _useSlotProps = useSlotProps({
51
52
  elementType: Field,
52
53
  externalSlotProps: innerSlotProps?.field,
54
+ externalForwardedProps: extractRootForwardedProps(props),
53
55
  additionalProps: _extends({}, isToolbarHidden && {
54
56
  id: labelId
55
57
  }),
@@ -63,7 +63,7 @@ const useStaticPicker = _ref => {
63
63
  }));
64
64
  const Layout = slots?.layout ?? PickerStaticLayout;
65
65
  const renderPicker = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_PickerProvider.PickerProvider, (0, _extends2.default)({}, providerProps, {
66
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Layout, (0, _extends2.default)({}, slotProps?.layout, {
66
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Layout, (0, _extends2.default)({}, (0, _utils.extractRootForwardedProps)(props), slotProps?.layout, {
67
67
  slots: slots,
68
68
  slotProps: slotProps,
69
69
  sx: (0, _utils.mergeSx)(providerProps.contextValue.rootSx, slotProps?.layout?.sx),
@@ -9,7 +9,7 @@ import { usePicker } from "../usePicker/index.mjs";
9
9
  import { PickerProvider } from "../../components/PickerProvider.mjs";
10
10
  import { PickersLayout } from "../../../PickersLayout/index.mjs";
11
11
  import { DIALOG_WIDTH } from "../../constants/dimensions.mjs";
12
- import { mergeSx } from "../../utils/utils.mjs";
12
+ import { extractRootForwardedProps, mergeSx } from "../../utils/utils.mjs";
13
13
  import { createNonRangePickerStepNavigation } from "../../utils/createNonRangePickerStepNavigation.mjs";
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
  const PickerStaticLayout = styled(PickersLayout, {
@@ -57,7 +57,7 @@ export const useStaticPicker = _ref => {
57
57
  }));
58
58
  const Layout = slots?.layout ?? PickerStaticLayout;
59
59
  const renderPicker = () => /*#__PURE__*/_jsx(PickerProvider, _extends({}, providerProps, {
60
- children: /*#__PURE__*/_jsx(Layout, _extends({}, slotProps?.layout, {
60
+ children: /*#__PURE__*/_jsx(Layout, _extends({}, extractRootForwardedProps(props), slotProps?.layout, {
61
61
  slots: slots,
62
62
  slotProps: slotProps,
63
63
  sx: mergeSx(providerProps.contextValue.rootSx, slotProps?.layout?.sx),
@@ -61,7 +61,7 @@ export { applyDefaultDate, replaceInvalidDateByNull, areDatesEqual, getTodayDate
61
61
  export { getDefaultReferenceDate } from "./utils/getDefaultReferenceDate.mjs";
62
62
  export { isTimeView, isInternalTimeView, resolveTimeFormat, getMeridiem, TIME_VIEWS } from "./utils/time-utils.mjs";
63
63
  export { resolveTimeViewsResponse, resolveDateTimeFormat } from "./utils/date-time-utils.mjs";
64
- export { executeInTheNextEventLoopTick, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.mjs";
64
+ export { executeInTheNextEventLoopTick, extractRootForwardedProps, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.mjs";
65
65
  export { useReduceAnimations } from "./hooks/useReduceAnimations.mjs";
66
66
  export { applyDefaultViewProps } from "./utils/views.mjs";
67
67
  export { isElementInteractive } from "./utils/isElementInteractive.mjs";
@@ -61,7 +61,7 @@ export { applyDefaultDate, replaceInvalidDateByNull, areDatesEqual, getTodayDate
61
61
  export { getDefaultReferenceDate } from "./utils/getDefaultReferenceDate.js";
62
62
  export { isTimeView, isInternalTimeView, resolveTimeFormat, getMeridiem, TIME_VIEWS } from "./utils/time-utils.js";
63
63
  export { resolveTimeViewsResponse, resolveDateTimeFormat } from "./utils/date-time-utils.js";
64
- export { executeInTheNextEventLoopTick, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.js";
64
+ export { executeInTheNextEventLoopTick, extractRootForwardedProps, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.js";
65
65
  export { useReduceAnimations } from "./hooks/useReduceAnimations.js";
66
66
  export { applyDefaultViewProps } from "./utils/views.js";
67
67
  export { isElementInteractive } from "./utils/isElementInteractive.js";
@@ -165,6 +165,12 @@ Object.defineProperty(exports, "executeInTheNextEventLoopTick", {
165
165
  return _utils.executeInTheNextEventLoopTick;
166
166
  }
167
167
  });
168
+ Object.defineProperty(exports, "extractRootForwardedProps", {
169
+ enumerable: true,
170
+ get: function () {
171
+ return _utils.extractRootForwardedProps;
172
+ }
173
+ });
168
174
  Object.defineProperty(exports, "formatMeridiem", {
169
175
  enumerable: true,
170
176
  get: function () {
@@ -30,7 +30,7 @@ export { applyDefaultDate, replaceInvalidDateByNull, areDatesEqual, getTodayDate
30
30
  export { getDefaultReferenceDate } from "./utils/getDefaultReferenceDate.mjs";
31
31
  export { isTimeView, isInternalTimeView, resolveTimeFormat, getMeridiem, TIME_VIEWS } from "./utils/time-utils.mjs";
32
32
  export { resolveTimeViewsResponse, resolveDateTimeFormat } from "./utils/date-time-utils.mjs";
33
- export { executeInTheNextEventLoopTick, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.mjs";
33
+ export { executeInTheNextEventLoopTick, extractRootForwardedProps, getActiveElement, onSpaceOrEnter, mergeSx, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from "./utils/utils.mjs";
34
34
  export { useReduceAnimations } from "./hooks/useReduceAnimations.mjs";
35
35
  export { applyDefaultViewProps } from "./utils/views.mjs";
36
36
  export { isElementInteractive } from "./utils/isElementInteractive.mjs";
@@ -19,4 +19,10 @@ export declare const getActiveElement: (node: Node | null | undefined) => Elemen
19
19
  */
20
20
  export declare const getFocusedListItemIndex: (listElement: HTMLUListElement) => number;
21
21
  export declare const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = "@media (pointer: fine)";
22
+ /**
23
+ * Picks any `data-*` and `aria-*` properties from `props` so they can be
24
+ * forwarded to the root DOM element rendered by the Picker. Other props stay
25
+ * owned by the Picker and are handled explicitly elsewhere.
26
+ */
27
+ export declare function extractRootForwardedProps<T extends object>(props: T): Record<string, unknown>;
22
28
  export declare function mergeSx(...sxProps: (SxProps<Theme> | undefined)[]): ReadonlyArray<boolean | SystemStyleObject<Theme> | ((theme: Theme) => SystemStyleObject<Theme>)>;
@@ -19,4 +19,10 @@ export declare const getActiveElement: (node: Node | null | undefined) => Elemen
19
19
  */
20
20
  export declare const getFocusedListItemIndex: (listElement: HTMLUListElement) => number;
21
21
  export declare const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = "@media (pointer: fine)";
22
+ /**
23
+ * Picks any `data-*` and `aria-*` properties from `props` so they can be
24
+ * forwarded to the root DOM element rendered by the Picker. Other props stay
25
+ * owned by the Picker and are handled explicitly elsewhere.
26
+ */
27
+ export declare function extractRootForwardedProps<T extends object>(props: T): Record<string, unknown>;
22
28
  export declare function mergeSx(...sxProps: (SxProps<Theme> | undefined)[]): ReadonlyArray<boolean | SystemStyleObject<Theme> | ((theme: Theme) => SystemStyleObject<Theme>)>;
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.DEFAULT_DESKTOP_MODE_MEDIA_QUERY = void 0;
8
8
  exports.arrayIncludes = arrayIncludes;
9
- exports.getFocusedListItemIndex = exports.getActiveElement = exports.executeInTheNextEventLoopTick = void 0;
9
+ exports.executeInTheNextEventLoopTick = void 0;
10
+ exports.extractRootForwardedProps = extractRootForwardedProps;
11
+ exports.getFocusedListItemIndex = exports.getActiveElement = void 0;
10
12
  exports.mergeSx = mergeSx;
11
13
  exports.onSpaceOrEnter = void 0;
12
14
  var _ownerDocument = _interopRequireDefault(require("@mui/utils/ownerDocument"));
@@ -70,6 +72,21 @@ const getFocusedListItemIndex = listElement => {
70
72
  };
71
73
  exports.getFocusedListItemIndex = getFocusedListItemIndex;
72
74
  const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = exports.DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
75
+
76
+ /**
77
+ * Picks any `data-*` and `aria-*` properties from `props` so they can be
78
+ * forwarded to the root DOM element rendered by the Picker. Other props stay
79
+ * owned by the Picker and are handled explicitly elsewhere.
80
+ */
81
+ function extractRootForwardedProps(props) {
82
+ const forwardedProps = {};
83
+ for (const key of Object.keys(props)) {
84
+ if (key.startsWith('data-') || key.startsWith('aria-')) {
85
+ forwardedProps[key] = props[key];
86
+ }
87
+ }
88
+ return forwardedProps;
89
+ }
73
90
  function mergeSx(...sxProps) {
74
91
  return sxProps.reduce((acc, sxProp) => {
75
92
  if (Array.isArray(sxProp)) {
@@ -55,6 +55,21 @@ export const getFocusedListItemIndex = listElement => {
55
55
  return children.indexOf(getActiveElement(listElement));
56
56
  };
57
57
  export const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
58
+
59
+ /**
60
+ * Picks any `data-*` and `aria-*` properties from `props` so they can be
61
+ * forwarded to the root DOM element rendered by the Picker. Other props stay
62
+ * owned by the Picker and are handled explicitly elsewhere.
63
+ */
64
+ export function extractRootForwardedProps(props) {
65
+ const forwardedProps = {};
66
+ for (const key of Object.keys(props)) {
67
+ if (key.startsWith('data-') || key.startsWith('aria-')) {
68
+ forwardedProps[key] = props[key];
69
+ }
70
+ }
71
+ return forwardedProps;
72
+ }
58
73
  export function mergeSx(...sxProps) {
59
74
  return sxProps.reduce((acc, sxProp) => {
60
75
  if (Array.isArray(sxProp)) {