@mui/x-date-pickers 8.9.0 β†’ 8.9.2

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,130 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.9.2
9
+
10
+ _Jul 31, 2025_
11
+
12
+ We'd like to extend a big thank you to the 23 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🌎 Improve French (fr-FR), Hebrew (he-IL) and Polish (pl-PL) locales on the Data Grid
15
+ - 🌎 Improve Korean (ko-KR) locale on the Date and Time Pickers
16
+ - πŸ“ˆ Add symlog scale to charts
17
+ - πŸ“Š Fix bar border radius on Firefox
18
+ - 🐞 Bugfixes
19
+ - πŸ“š Documentation improvements
20
+
21
+ Special thanks go out to the community members for their valuable contributions:
22
+ @AmrElnaggar99, @atlanteh, @ddolcimascolo, @Jiseoup, @leonaha5, @noherczeg, @sai6855
23
+
24
+ The following are all team members who have contributed to this release:
25
+ @alexfauquette, @arminmeh, @bernardobelchior, @bharatkashyap, @brijeshb42, @cherniavskii, @flaviendelangle, @Janpot, @JCQuintas, @KenanYusuf, @LukasTy, @mapache-salvaje, @MBilalShafi, @rita-codes, @romgrk, @siriwatknp
26
+
27
+ ### Data Grid
28
+
29
+ #### `@mui/x-data-grid@8.9.2`
30
+
31
+ - [DataGrid] Add debounce for columns panel search (#18719) @noherczeg
32
+ - [DataGrid] Extract virtualization engine (#18275) @romgrk
33
+ - [DataGrid] Improve types in `<GridEditSingleSelect />` (#18184) @sai6855
34
+ - [l10n] Improve French (fr-FR) locale (#18905) @ddolcimascolo
35
+ - [l10n] Improve Hebrew (he-IL) locale (#18665) @atlanteh
36
+ - [l10n] Improve Polish (pl-PL) locale (#18068) @leonaha5
37
+
38
+ #### `@mui/x-data-grid-pro@8.9.2` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
39
+
40
+ Same changes as in `@mui/x-data-grid@8.9.2`, plus:
41
+
42
+ - [DataGridPro] Fix duplicate nested rows for dynamically updated row IDs (#18526) @MBilalShafi
43
+
44
+ #### `@mui/x-data-grid-premium@8.9.2` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
45
+
46
+ Same changes as in `@mui/x-data-grid-pro@8.9.2`, plus:
47
+
48
+ - [DataGridPremium] Add `privateMode` to AI assistant prompt resolver (#18759) @bharatkashyap
49
+ - [DataGridPremium] Fix empty nested group values caused by main criterial `valueFormatter()` (#18916) @cherniavskii
50
+ - [DataGridPremium] Sidebar content and state is managed the same way as for preference panel (#18741) @arminmeh
51
+ - [DataGridPremium] Make `api` param for the aggregation function optional (#18984) @arminmeh
52
+
53
+ ### Date and Time Pickers
54
+
55
+ #### `@mui/x-date-pickers@8.9.2`
56
+
57
+ - [l10n] Improve Korean (ko-KR) locale (#18664) @Jiseoup
58
+ - [pickers] Fix popper click-away behavior (#18804) @LukasTy
59
+ - [pickers] Fix usage not in main document (#18944) @LukasTy
60
+
61
+ #### `@mui/x-date-pickers-pro@8.9.2` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
62
+
63
+ Same changes as in `@mui/x-date-pickers@8.9.2`.
64
+
65
+ ### Charts
66
+
67
+ #### `@mui/x-charts@8.9.2`
68
+
69
+ - [charts] Add symlog scale to charts (#18729) @bernardobelchior
70
+ - [charts] Fix bar border radius on Firefox (#18824) @bernardobelchior
71
+ - [charts] Fix crash when rendering large scatter dataset (#18845) @bernardobelchior
72
+ - [charts] Remove unnecessary type assertion in tooltip `valueFormatter()` (#18877) @sai6855
73
+ - [charts] Export `ChartsWrapper` from `'./ChartsWrapper'` rather than `'./internals'` (#18966) @JCQuintas
74
+
75
+ #### `@mui/x-charts-pro@8.9.2` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
76
+
77
+ Same changes as in `@mui/x-charts@8.9.2`, plus:
78
+
79
+ - [charts-pro] Fix voronoi interaction with zoom (#18950) @alexfauquette
80
+ - [charts-pro] Hide toolbar by default when exporting (#18764) @bernardobelchior
81
+
82
+ ### Codemod
83
+
84
+ #### `@mui/x-codemod@8.9.2`
85
+
86
+ Internal changes.
87
+
88
+ ### Docs
89
+
90
+ - [docs] Add Data Grid demo pages (#18180) @KenanYusuf
91
+ - [docs] Copyedit the Charts Overview page (#18840) @mapache-salvaje
92
+ - [docs] Fix incorrect parameter name in pickers "Custom components" page from `variant` to `pickerVariant` (#18919) @AmrElnaggar99
93
+
94
+ ### Miscellaneous
95
+
96
+ - [code-infra] Auto-generate deep exports to prevent asymmetric exports (#18917) @JCQuintas
97
+ - [docs-infra] Turn on "Edit in Chat" for X docs (#18869) @siriwatknp
98
+ - [infra] Add specific bundle size tracking (#18884) @Janpot
99
+ - [infra] Fix markdown formatting in llms generation (#18914) @Janpot
100
+ - [infra] Use CI action from mui-public (#18709) @brijeshb42
101
+
102
+ ## 8.9.1
103
+
104
+ _Jul 21, 2025_
105
+
106
+ We'd like to extend a big thank you to the 2 contributors who made this release possible. Here are some highlights ✨:
107
+
108
+ 🐞 Fix package publish issue
109
+
110
+ The following are all team members who have contributed to this release:
111
+ @KenanYusuf, @MBilalShafi
112
+
113
+ ### Data Grid
114
+
115
+ #### `@mui/x-data-grid@8.9.1`
116
+
117
+ - [DataGrid] Move conditional list view column logic into `gridVisibleColumnDefinitionsSelector` (#18724) @KenanYusuf
118
+ - [DataGrid] Fix row selection "exclude" model inconsistency (#18844) @MBilalShafi
119
+
120
+ #### `@mui/x-data-grid-pro@8.9.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
121
+
122
+ Same changes as in `@mui/x-data-grid@8.9.1`.
123
+
124
+ #### `@mui/x-data-grid-premium@8.9.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
125
+
126
+ Same changes as in `@mui/x-data-grid-pro@8.9.1`.
127
+
128
+ ### Core
129
+
130
+ - [core] Follow yml syntax convention @oliviertassinari
131
+
8
132
  ## 8.9.0
9
133
 
10
134
  _Jul 17, 2025_
@@ -188,6 +188,7 @@ const PickerDay2Raw = /*#__PURE__*/React.forwardRef(function PickerDay2(inProps,
188
188
  }
189
189
  };
190
190
  const handleClick = event => {
191
+ event.defaultMuiPrevented = true;
191
192
  if (!disabled) {
192
193
  onDaySelect(day);
193
194
  }
@@ -193,6 +193,7 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
193
193
  }
194
194
  };
195
195
  const handleClick = event => {
196
+ event.defaultMuiPrevented = true;
196
197
  if (!disabled) {
197
198
  onDaySelect(day);
198
199
  }
@@ -180,6 +180,7 @@ const PickerDay2Raw = /*#__PURE__*/React.forwardRef(function PickerDay2(inProps,
180
180
  }
181
181
  };
182
182
  const handleClick = event => {
183
+ event.defaultMuiPrevented = true;
183
184
  if (!disabled) {
184
185
  onDaySelect(day);
185
186
  }
@@ -186,6 +186,7 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
186
186
  }
187
187
  };
188
188
  const handleClick = event => {
189
+ event.defaultMuiPrevented = true;
189
190
  if (!disabled) {
190
191
  onDaySelect(day);
191
192
  }
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v8.9.0
2
+ * @mui/x-date-pickers v8.9.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -129,8 +129,11 @@ function useClickAwayListener(active, onClickAway) {
129
129
  });
130
130
 
131
131
  // Keep track of mouse/touch events that bubbled up through the portal.
132
- const handleSynthetic = () => {
133
- syntheticEventRef.current = true;
132
+ const handleSynthetic = event => {
133
+ // Ignore events handled by our internal components
134
+ if (!event.defaultMuiPrevented) {
135
+ syntheticEventRef.current = true;
136
+ }
134
137
  };
135
138
  React.useEffect(() => {
136
139
  if (active) {
@@ -220,6 +223,10 @@ export function PickerPopper(inProps) {
220
223
  popupRef,
221
224
  reduceAnimations
222
225
  } = usePickerContext();
226
+ const {
227
+ ownerState: pickerOwnerState,
228
+ rootRefObject
229
+ } = usePickerPrivateContext();
223
230
  const {
224
231
  dismissViews,
225
232
  getCurrentViewMode,
@@ -244,7 +251,7 @@ export function PickerPopper(inProps) {
244
251
  return;
245
252
  }
246
253
  if (open) {
247
- lastFocusedElementRef.current = getActiveElement(document);
254
+ lastFocusedElementRef.current = getActiveElement(rootRefObject.current);
248
255
  } else if (lastFocusedElementRef.current && lastFocusedElementRef.current instanceof HTMLElement) {
249
256
  // make sure the button is flushed with updated label, before returning focus to it
250
257
  // avoids issue, where screen reader could fail to announce selected date after selection
@@ -254,16 +261,12 @@ export function PickerPopper(inProps) {
254
261
  }
255
262
  });
256
263
  }
257
- }, [open, viewContainerRole, getCurrentViewMode]);
264
+ }, [open, viewContainerRole, getCurrentViewMode, rootRefObject]);
258
265
  const classes = useUtilityClasses(classesProp);
259
- const {
260
- ownerState: pickerOwnerState,
261
- rootRefObject
262
- } = usePickerPrivateContext();
263
266
  const handleClickAway = useEventCallback(() => {
264
267
  if (viewContainerRole === 'tooltip') {
265
268
  executeInTheNextEventLoopTick(() => {
266
- if (rootRefObject.current?.contains(getActiveElement(document)) || popupRef.current?.contains(getActiveElement(document))) {
269
+ if (rootRefObject.current?.contains(getActiveElement(rootRefObject.current)) || popupRef.current?.contains(getActiveElement(popupRef.current))) {
267
270
  return;
268
271
  }
269
272
  dismissViews();
@@ -1,3 +1,4 @@
1
+ import ownerDocument from '@mui/utils/ownerDocument';
1
2
  import { getActiveElement } from "../../utils/utils.js";
2
3
  export function syncSelectionToDOM(parameters) {
3
4
  const {
@@ -12,7 +13,7 @@ export function syncSelectionToDOM(parameters) {
12
13
  if (!domGetters.isReady()) {
13
14
  return;
14
15
  }
15
- const selection = document.getSelection();
16
+ const selection = ownerDocument(domGetters.getRoot()).getSelection();
16
17
  if (!selection) {
17
18
  return;
18
19
  }
@@ -28,7 +29,7 @@ export function syncSelectionToDOM(parameters) {
28
29
  }
29
30
 
30
31
  // On multi input range pickers we want to update selection range only for the active input
31
- if (!domGetters.getRoot().contains(getActiveElement(document))) {
32
+ if (!domGetters.getRoot().contains(getActiveElement(domGetters.getRoot()))) {
32
33
  return;
33
34
  }
34
35
  const range = new window.Range();
@@ -116,7 +116,7 @@ export function useFieldRootProps(parameters) {
116
116
  if (focused || disabled || !domGetters.isReady()) {
117
117
  return;
118
118
  }
119
- const activeElement = getActiveElement(document);
119
+ const activeElement = getActiveElement(domGetters.getRoot());
120
120
  setFocused(true);
121
121
  const isFocusInsideASection = domGetters.getSectionIndexFromDOMElement(activeElement) != null;
122
122
  if (!isFocusInsideASection) {
@@ -128,7 +128,7 @@ export function useFieldRootProps(parameters) {
128
128
  if (!domGetters.isReady()) {
129
129
  return;
130
130
  }
131
- const activeElement = getActiveElement(document);
131
+ const activeElement = getActiveElement(domGetters.getRoot());
132
132
  const shouldBlur = !domGetters.getRoot().contains(activeElement);
133
133
  if (shouldBlur) {
134
134
  setFocused(false);
@@ -133,7 +133,7 @@ export const useFieldV6TextField = parameters => {
133
133
  setSelectedSections(sectionIndex);
134
134
  }
135
135
  function focusField(newSelectedSection = 0) {
136
- if (getActiveElement(document) === inputRef.current) {
136
+ if (getActiveElement(inputRef.current) === inputRef.current) {
137
137
  return;
138
138
  }
139
139
  inputRef.current?.focus();
@@ -298,7 +298,7 @@ export const useFieldV6TextField = parameters => {
298
298
  const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getV6InputValueFromSections(state.sections, localizedDigits, isRtl), [state.sections, fieldValueManager, state.tempValueStrAndroid, localizedDigits, isRtl]);
299
299
  React.useEffect(() => {
300
300
  // Select all the sections when focused on mount (`autoFocus = true` on the input)
301
- if (inputRef.current && inputRef.current === getActiveElement(document)) {
301
+ if (inputRef.current && inputRef.current === getActiveElement(inputRef.current)) {
302
302
  setSelectedSections('all');
303
303
  }
304
304
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
@@ -321,7 +321,7 @@ export const useFieldV6TextField = parameters => {
321
321
  // On multi input range pickers we want to update selection range only for the active input
322
322
  // This helps to avoid the focus jumping on Safari https://github.com/mui/mui-x/issues/9003
323
323
  // because WebKit implements the `setSelectionRange` based on the spec: https://bugs.webkit.org/show_bug.cgi?id=224425
324
- if (inputRef.current !== getActiveElement(document)) {
324
+ if (inputRef.current !== getActiveElement(inputRef.current)) {
325
325
  return;
326
326
  }
327
327
 
@@ -334,14 +334,14 @@ export const useFieldV6TextField = parameters => {
334
334
  const selectionStart = selectedSection.type === 'empty' ? selectedSection.startInInput - selectedSection.startSeparator.length : selectedSection.startInInput;
335
335
  const selectionEnd = selectedSection.type === 'empty' ? selectedSection.endInInput + selectedSection.endSeparator.length : selectedSection.endInInput;
336
336
  if (selectionStart !== inputRef.current.selectionStart || selectionEnd !== inputRef.current.selectionEnd) {
337
- if (inputRef.current === getActiveElement(document)) {
337
+ if (inputRef.current === getActiveElement(inputRef.current)) {
338
338
  inputRef.current.setSelectionRange(selectionStart, selectionEnd);
339
339
  }
340
340
  }
341
341
  selectionSyncTimeout.start(0, () => {
342
342
  // handle case when the selection is not updated correctly
343
343
  // could happen on Android
344
- if (inputRef.current && inputRef.current === getActiveElement(document) &&
344
+ if (inputRef.current && inputRef.current === getActiveElement(inputRef.current) &&
345
345
  // The section might loose all selection, where `selectionStart === selectionEnd`
346
346
  // https://github.com/mui/mui-x/pull/13652
347
347
  inputRef.current.selectionStart === inputRef.current.selectionEnd && (inputRef.current.selectionStart !== selectionStart || inputRef.current.selectionEnd !== selectionEnd)) {
@@ -364,7 +364,7 @@ export const useFieldV6TextField = parameters => {
364
364
  }
365
365
  return 'numeric';
366
366
  }, [activeSectionIndex, state.sections]);
367
- const inputHasFocus = inputRef.current && inputRef.current === getActiveElement(document);
367
+ const inputHasFocus = inputRef.current && inputRef.current === getActiveElement(inputRef.current);
368
368
  const shouldShowPlaceholder = !inputHasFocus && areAllSectionsEmpty;
369
369
  React.useImperativeHandle(unstableFieldRef, () => ({
370
370
  getSections: () => state.sections,
@@ -407,5 +407,5 @@ export const useFieldV6TextField = parameters => {
407
407
  });
408
408
  };
409
409
  function isFieldFocused(inputRef) {
410
- return inputRef.current === getActiveElement(document);
410
+ return inputRef.current === getActiveElement(inputRef.current);
411
411
  }
@@ -243,13 +243,13 @@ export const useFieldV7TextField = parameters => {
243
243
  });
244
244
  };
245
245
  function getActiveSectionIndex(sectionListRef) {
246
- const activeElement = getActiveElement(document);
246
+ const activeElement = getActiveElement(sectionListRef.current?.getRoot());
247
247
  if (!activeElement || !sectionListRef.current || !sectionListRef.current.getRoot().contains(activeElement)) {
248
248
  return null;
249
249
  }
250
250
  return sectionListRef.current.getSectionIndexFromDOMElement(activeElement);
251
251
  }
252
252
  function isFieldFocused(sectionListRef) {
253
- const activeElement = getActiveElement(document);
253
+ const activeElement = getActiveElement(sectionListRef.current?.getRoot());
254
254
  return !!sectionListRef.current && sectionListRef.current.getRoot().contains(activeElement);
255
255
  }
@@ -4,7 +4,13 @@ import * as React from 'react';
4
4
  export declare function arrayIncludes<T>(array: T[] | readonly T[], itemOrItems: T | T[]): boolean;
5
5
  export declare const onSpaceOrEnter: (innerFn: (ev: React.MouseEvent<any> | React.KeyboardEvent<any>) => void, externalEvent?: (event: React.KeyboardEvent<any>) => void) => (event: React.KeyboardEvent) => void;
6
6
  export declare const executeInTheNextEventLoopTick: (fn: () => void) => void;
7
- export declare const getActiveElement: (root?: Document | ShadowRoot) => Element | null;
7
+ /**
8
+ * Gets the currently active element within a given node's document.
9
+ * This function traverses shadow DOM if necessary.
10
+ * @param node - The node from which to get the active element.
11
+ * @returns The currently active element, or null if none is found.
12
+ */
13
+ export declare const getActiveElement: (node: Node | null | undefined) => Element | null;
8
14
  /**
9
15
  * Gets the index of the focused list item in a given ul list element.
10
16
  *
@@ -1,3 +1,4 @@
1
+ import ownerDocument from '@mui/utils/ownerDocument';
1
2
  /* Use it instead of .includes method for IE support */
2
3
  export function arrayIncludes(array, itemOrItems) {
3
4
  if (Array.isArray(itemOrItems)) {
@@ -22,17 +23,27 @@ export const executeInTheNextEventLoopTick = fn => {
22
23
  };
23
24
 
24
25
  // https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/
25
- export const getActiveElement = (root = document) => {
26
+ const getActiveElementInternal = (root = document) => {
26
27
  const activeEl = root.activeElement;
27
28
  if (!activeEl) {
28
29
  return null;
29
30
  }
30
31
  if (activeEl.shadowRoot) {
31
- return getActiveElement(activeEl.shadowRoot);
32
+ return getActiveElementInternal(activeEl.shadowRoot);
32
33
  }
33
34
  return activeEl;
34
35
  };
35
36
 
37
+ /**
38
+ * Gets the currently active element within a given node's document.
39
+ * This function traverses shadow DOM if necessary.
40
+ * @param node - The node from which to get the active element.
41
+ * @returns The currently active element, or null if none is found.
42
+ */
43
+ export const getActiveElement = node => {
44
+ return getActiveElementInternal(ownerDocument(node));
45
+ };
46
+
36
47
  /**
37
48
  * Gets the index of the focused list item in a given ul list element.
38
49
  *
@@ -41,7 +52,7 @@ export const getActiveElement = (root = document) => {
41
52
  */
42
53
  export const getFocusedListItemIndex = listElement => {
43
54
  const children = Array.from(listElement.children);
44
- return children.indexOf(getActiveElement(document));
55
+ return children.indexOf(getActiveElement(listElement));
45
56
  };
46
57
  export const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
47
58
  export function mergeSx(...sxProps) {
@@ -31,8 +31,7 @@ const koKRPickers = {
31
31
  dateTimePickerToolbarTitle: 'λ‚ μ§œ & μ‹œκ°„ μ„ νƒν•˜κΈ°',
32
32
  timePickerToolbarTitle: 'μ‹œκ°„ μ„ νƒν•˜κΈ°',
33
33
  dateRangePickerToolbarTitle: 'λ‚ μ§œ λ²”μœ„ μ„ νƒν•˜κΈ°',
34
- // timeRangePickerToolbarTitle: 'Select time range',
35
-
34
+ timeRangePickerToolbarTitle: 'μ‹œκ°„ λ²”μœ„ μ„ νƒν•˜κΈ°',
36
35
  // Clock labels
37
36
  clockLabelText: (view, formattedTime) => `${views[view]} μ„ νƒν•˜μ„Έμš”. ${!formattedTime ? 'μ‹œκ°„μ„ μ„ νƒν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.' : `ν˜„μž¬ μ„ νƒλœ μ‹œκ°„μ€ ${formattedTime}μž…λ‹ˆλ‹€.`}`,
38
37
  hoursClockNumberText: hours => `${hours}μ‹œ`,
@@ -48,7 +47,7 @@ const koKRPickers = {
48
47
  // Open Picker labels
49
48
  openDatePickerDialogue: formattedDate => formattedDate ? `λ‚ μ§œλ₯Ό μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ λ‚ μ§œλŠ” ${formattedDate}μž…λ‹ˆλ‹€.` : 'λ‚ μ§œλ₯Ό μ„ νƒν•˜μ„Έμš”',
50
49
  openTimePickerDialogue: formattedTime => formattedTime ? `μ‹œκ°„μ„ μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ μ‹œκ°„μ€ ${formattedTime}μž…λ‹ˆλ‹€.` : 'μ‹œκ°„μ„ μ„ νƒν•˜μ„Έμš”',
51
- // openRangePickerDialogue: formattedRange => formattedRange ? `Choose range, selected range is ${formattedRange}` : 'Choose range',
50
+ openRangePickerDialogue: formattedRange => formattedRange ? `λ²”μœ„λ₯Ό μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ λ²”μœ„λŠ” ${formattedRange}μž…λ‹ˆλ‹€.` : 'λ²”μœ„λ₯Ό μ„ νƒν•˜μ„Έμš”',
52
51
  fieldClearLabel: 'μ§€μš°κΈ°',
53
52
  // Table labels
54
53
  timeTableLabel: 'μ„ νƒν•œ μ‹œκ°„',
@@ -70,8 +69,7 @@ const koKRPickers = {
70
69
  hours: 'μ‹œκ°„',
71
70
  minutes: 'λΆ„',
72
71
  seconds: '초',
73
- // meridiem: 'Meridiem',
74
-
72
+ meridiem: 'μ˜€μ „/μ˜€ν›„',
75
73
  // Common
76
74
  empty: 'κ³΅λž€'
77
75
  };
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v8.9.0
2
+ * @mui/x-date-pickers v8.9.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -136,8 +136,11 @@ function useClickAwayListener(active, onClickAway) {
136
136
  });
137
137
 
138
138
  // Keep track of mouse/touch events that bubbled up through the portal.
139
- const handleSynthetic = () => {
140
- syntheticEventRef.current = true;
139
+ const handleSynthetic = event => {
140
+ // Ignore events handled by our internal components
141
+ if (!event.defaultMuiPrevented) {
142
+ syntheticEventRef.current = true;
143
+ }
141
144
  };
142
145
  React.useEffect(() => {
143
146
  if (active) {
@@ -227,6 +230,10 @@ function PickerPopper(inProps) {
227
230
  popupRef,
228
231
  reduceAnimations
229
232
  } = (0, _hooks.usePickerContext)();
233
+ const {
234
+ ownerState: pickerOwnerState,
235
+ rootRefObject
236
+ } = (0, _usePickerPrivateContext.usePickerPrivateContext)();
230
237
  const {
231
238
  dismissViews,
232
239
  getCurrentViewMode,
@@ -251,7 +258,7 @@ function PickerPopper(inProps) {
251
258
  return;
252
259
  }
253
260
  if (open) {
254
- lastFocusedElementRef.current = (0, _utils.getActiveElement)(document);
261
+ lastFocusedElementRef.current = (0, _utils.getActiveElement)(rootRefObject.current);
255
262
  } else if (lastFocusedElementRef.current && lastFocusedElementRef.current instanceof HTMLElement) {
256
263
  // make sure the button is flushed with updated label, before returning focus to it
257
264
  // avoids issue, where screen reader could fail to announce selected date after selection
@@ -261,16 +268,12 @@ function PickerPopper(inProps) {
261
268
  }
262
269
  });
263
270
  }
264
- }, [open, viewContainerRole, getCurrentViewMode]);
271
+ }, [open, viewContainerRole, getCurrentViewMode, rootRefObject]);
265
272
  const classes = useUtilityClasses(classesProp);
266
- const {
267
- ownerState: pickerOwnerState,
268
- rootRefObject
269
- } = (0, _usePickerPrivateContext.usePickerPrivateContext)();
270
273
  const handleClickAway = (0, _useEventCallback.default)(() => {
271
274
  if (viewContainerRole === 'tooltip') {
272
275
  (0, _utils.executeInTheNextEventLoopTick)(() => {
273
- if (rootRefObject.current?.contains((0, _utils.getActiveElement)(document)) || popupRef.current?.contains((0, _utils.getActiveElement)(document))) {
276
+ if (rootRefObject.current?.contains((0, _utils.getActiveElement)(rootRefObject.current)) || popupRef.current?.contains((0, _utils.getActiveElement)(popupRef.current))) {
274
277
  return;
275
278
  }
276
279
  dismissViews();
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.syncSelectionToDOM = syncSelectionToDOM;
8
+ var _ownerDocument = _interopRequireDefault(require("@mui/utils/ownerDocument"));
7
9
  var _utils = require("../../utils/utils");
8
10
  function syncSelectionToDOM(parameters) {
9
11
  const {
@@ -18,7 +20,7 @@ function syncSelectionToDOM(parameters) {
18
20
  if (!domGetters.isReady()) {
19
21
  return;
20
22
  }
21
- const selection = document.getSelection();
23
+ const selection = (0, _ownerDocument.default)(domGetters.getRoot()).getSelection();
22
24
  if (!selection) {
23
25
  return;
24
26
  }
@@ -34,7 +36,7 @@ function syncSelectionToDOM(parameters) {
34
36
  }
35
37
 
36
38
  // On multi input range pickers we want to update selection range only for the active input
37
- if (!domGetters.getRoot().contains((0, _utils.getActiveElement)(document))) {
39
+ if (!domGetters.getRoot().contains((0, _utils.getActiveElement)(domGetters.getRoot()))) {
38
40
  return;
39
41
  }
40
42
  const range = new window.Range();
@@ -122,7 +122,7 @@ function useFieldRootProps(parameters) {
122
122
  if (focused || disabled || !domGetters.isReady()) {
123
123
  return;
124
124
  }
125
- const activeElement = (0, _utils.getActiveElement)(document);
125
+ const activeElement = (0, _utils.getActiveElement)(domGetters.getRoot());
126
126
  setFocused(true);
127
127
  const isFocusInsideASection = domGetters.getSectionIndexFromDOMElement(activeElement) != null;
128
128
  if (!isFocusInsideASection) {
@@ -134,7 +134,7 @@ function useFieldRootProps(parameters) {
134
134
  if (!domGetters.isReady()) {
135
135
  return;
136
136
  }
137
- const activeElement = (0, _utils.getActiveElement)(document);
137
+ const activeElement = (0, _utils.getActiveElement)(domGetters.getRoot());
138
138
  const shouldBlur = !domGetters.getRoot().contains(activeElement);
139
139
  if (shouldBlur) {
140
140
  setFocused(false);
@@ -141,7 +141,7 @@ const useFieldV6TextField = parameters => {
141
141
  setSelectedSections(sectionIndex);
142
142
  }
143
143
  function focusField(newSelectedSection = 0) {
144
- if ((0, _utils.getActiveElement)(document) === inputRef.current) {
144
+ if ((0, _utils.getActiveElement)(inputRef.current) === inputRef.current) {
145
145
  return;
146
146
  }
147
147
  inputRef.current?.focus();
@@ -306,7 +306,7 @@ const useFieldV6TextField = parameters => {
306
306
  const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getV6InputValueFromSections(state.sections, localizedDigits, isRtl), [state.sections, fieldValueManager, state.tempValueStrAndroid, localizedDigits, isRtl]);
307
307
  React.useEffect(() => {
308
308
  // Select all the sections when focused on mount (`autoFocus = true` on the input)
309
- if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document)) {
309
+ if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(inputRef.current)) {
310
310
  setSelectedSections('all');
311
311
  }
312
312
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
@@ -329,7 +329,7 @@ const useFieldV6TextField = parameters => {
329
329
  // On multi input range pickers we want to update selection range only for the active input
330
330
  // This helps to avoid the focus jumping on Safari https://github.com/mui/mui-x/issues/9003
331
331
  // because WebKit implements the `setSelectionRange` based on the spec: https://bugs.webkit.org/show_bug.cgi?id=224425
332
- if (inputRef.current !== (0, _utils.getActiveElement)(document)) {
332
+ if (inputRef.current !== (0, _utils.getActiveElement)(inputRef.current)) {
333
333
  return;
334
334
  }
335
335
 
@@ -342,14 +342,14 @@ const useFieldV6TextField = parameters => {
342
342
  const selectionStart = selectedSection.type === 'empty' ? selectedSection.startInInput - selectedSection.startSeparator.length : selectedSection.startInInput;
343
343
  const selectionEnd = selectedSection.type === 'empty' ? selectedSection.endInInput + selectedSection.endSeparator.length : selectedSection.endInInput;
344
344
  if (selectionStart !== inputRef.current.selectionStart || selectionEnd !== inputRef.current.selectionEnd) {
345
- if (inputRef.current === (0, _utils.getActiveElement)(document)) {
345
+ if (inputRef.current === (0, _utils.getActiveElement)(inputRef.current)) {
346
346
  inputRef.current.setSelectionRange(selectionStart, selectionEnd);
347
347
  }
348
348
  }
349
349
  selectionSyncTimeout.start(0, () => {
350
350
  // handle case when the selection is not updated correctly
351
351
  // could happen on Android
352
- if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document) &&
352
+ if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(inputRef.current) &&
353
353
  // The section might loose all selection, where `selectionStart === selectionEnd`
354
354
  // https://github.com/mui/mui-x/pull/13652
355
355
  inputRef.current.selectionStart === inputRef.current.selectionEnd && (inputRef.current.selectionStart !== selectionStart || inputRef.current.selectionEnd !== selectionEnd)) {
@@ -372,7 +372,7 @@ const useFieldV6TextField = parameters => {
372
372
  }
373
373
  return 'numeric';
374
374
  }, [activeSectionIndex, state.sections]);
375
- const inputHasFocus = inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document);
375
+ const inputHasFocus = inputRef.current && inputRef.current === (0, _utils.getActiveElement)(inputRef.current);
376
376
  const shouldShowPlaceholder = !inputHasFocus && areAllSectionsEmpty;
377
377
  React.useImperativeHandle(unstableFieldRef, () => ({
378
378
  getSections: () => state.sections,
@@ -416,5 +416,5 @@ const useFieldV6TextField = parameters => {
416
416
  };
417
417
  exports.useFieldV6TextField = useFieldV6TextField;
418
418
  function isFieldFocused(inputRef) {
419
- return inputRef.current === (0, _utils.getActiveElement)(document);
419
+ return inputRef.current === (0, _utils.getActiveElement)(inputRef.current);
420
420
  }
@@ -251,13 +251,13 @@ const useFieldV7TextField = parameters => {
251
251
  };
252
252
  exports.useFieldV7TextField = useFieldV7TextField;
253
253
  function getActiveSectionIndex(sectionListRef) {
254
- const activeElement = (0, _utils.getActiveElement)(document);
254
+ const activeElement = (0, _utils.getActiveElement)(sectionListRef.current?.getRoot());
255
255
  if (!activeElement || !sectionListRef.current || !sectionListRef.current.getRoot().contains(activeElement)) {
256
256
  return null;
257
257
  }
258
258
  return sectionListRef.current.getSectionIndexFromDOMElement(activeElement);
259
259
  }
260
260
  function isFieldFocused(sectionListRef) {
261
- const activeElement = (0, _utils.getActiveElement)(document);
261
+ const activeElement = (0, _utils.getActiveElement)(sectionListRef.current?.getRoot());
262
262
  return !!sectionListRef.current && sectionListRef.current.getRoot().contains(activeElement);
263
263
  }
@@ -4,7 +4,13 @@ import * as React from 'react';
4
4
  export declare function arrayIncludes<T>(array: T[] | readonly T[], itemOrItems: T | T[]): boolean;
5
5
  export declare const onSpaceOrEnter: (innerFn: (ev: React.MouseEvent<any> | React.KeyboardEvent<any>) => void, externalEvent?: (event: React.KeyboardEvent<any>) => void) => (event: React.KeyboardEvent) => void;
6
6
  export declare const executeInTheNextEventLoopTick: (fn: () => void) => void;
7
- export declare const getActiveElement: (root?: Document | ShadowRoot) => Element | null;
7
+ /**
8
+ * Gets the currently active element within a given node's document.
9
+ * This function traverses shadow DOM if necessary.
10
+ * @param node - The node from which to get the active element.
11
+ * @returns The currently active element, or null if none is found.
12
+ */
13
+ export declare const getActiveElement: (node: Node | null | undefined) => Element | null;
8
14
  /**
9
15
  * Gets the index of the focused list item in a given ul list element.
10
16
  *
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -8,6 +9,7 @@ exports.arrayIncludes = arrayIncludes;
8
9
  exports.getFocusedListItemIndex = exports.getActiveElement = exports.executeInTheNextEventLoopTick = void 0;
9
10
  exports.mergeSx = mergeSx;
10
11
  exports.onSpaceOrEnter = void 0;
12
+ var _ownerDocument = _interopRequireDefault(require("@mui/utils/ownerDocument"));
11
13
  /* Use it instead of .includes method for IE support */
12
14
  function arrayIncludes(array, itemOrItems) {
13
15
  if (Array.isArray(itemOrItems)) {
@@ -34,17 +36,27 @@ const executeInTheNextEventLoopTick = fn => {
34
36
 
35
37
  // https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/
36
38
  exports.executeInTheNextEventLoopTick = executeInTheNextEventLoopTick;
37
- const getActiveElement = (root = document) => {
39
+ const getActiveElementInternal = (root = document) => {
38
40
  const activeEl = root.activeElement;
39
41
  if (!activeEl) {
40
42
  return null;
41
43
  }
42
44
  if (activeEl.shadowRoot) {
43
- return getActiveElement(activeEl.shadowRoot);
45
+ return getActiveElementInternal(activeEl.shadowRoot);
44
46
  }
45
47
  return activeEl;
46
48
  };
47
49
 
50
+ /**
51
+ * Gets the currently active element within a given node's document.
52
+ * This function traverses shadow DOM if necessary.
53
+ * @param node - The node from which to get the active element.
54
+ * @returns The currently active element, or null if none is found.
55
+ */
56
+ const getActiveElement = node => {
57
+ return getActiveElementInternal((0, _ownerDocument.default)(node));
58
+ };
59
+
48
60
  /**
49
61
  * Gets the index of the focused list item in a given ul list element.
50
62
  *
@@ -54,7 +66,7 @@ const getActiveElement = (root = document) => {
54
66
  exports.getActiveElement = getActiveElement;
55
67
  const getFocusedListItemIndex = listElement => {
56
68
  const children = Array.from(listElement.children);
57
- return children.indexOf(getActiveElement(document));
69
+ return children.indexOf(getActiveElement(listElement));
58
70
  };
59
71
  exports.getFocusedListItemIndex = getFocusedListItemIndex;
60
72
  const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = exports.DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
package/locales/koKR.js CHANGED
@@ -37,8 +37,7 @@ const koKRPickers = {
37
37
  dateTimePickerToolbarTitle: 'λ‚ μ§œ & μ‹œκ°„ μ„ νƒν•˜κΈ°',
38
38
  timePickerToolbarTitle: 'μ‹œκ°„ μ„ νƒν•˜κΈ°',
39
39
  dateRangePickerToolbarTitle: 'λ‚ μ§œ λ²”μœ„ μ„ νƒν•˜κΈ°',
40
- // timeRangePickerToolbarTitle: 'Select time range',
41
-
40
+ timeRangePickerToolbarTitle: 'μ‹œκ°„ λ²”μœ„ μ„ νƒν•˜κΈ°',
42
41
  // Clock labels
43
42
  clockLabelText: (view, formattedTime) => `${views[view]} μ„ νƒν•˜μ„Έμš”. ${!formattedTime ? 'μ‹œκ°„μ„ μ„ νƒν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.' : `ν˜„μž¬ μ„ νƒλœ μ‹œκ°„μ€ ${formattedTime}μž…λ‹ˆλ‹€.`}`,
44
43
  hoursClockNumberText: hours => `${hours}μ‹œ`,
@@ -54,7 +53,7 @@ const koKRPickers = {
54
53
  // Open Picker labels
55
54
  openDatePickerDialogue: formattedDate => formattedDate ? `λ‚ μ§œλ₯Ό μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ λ‚ μ§œλŠ” ${formattedDate}μž…λ‹ˆλ‹€.` : 'λ‚ μ§œλ₯Ό μ„ νƒν•˜μ„Έμš”',
56
55
  openTimePickerDialogue: formattedTime => formattedTime ? `μ‹œκ°„μ„ μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ μ‹œκ°„μ€ ${formattedTime}μž…λ‹ˆλ‹€.` : 'μ‹œκ°„μ„ μ„ νƒν•˜μ„Έμš”',
57
- // openRangePickerDialogue: formattedRange => formattedRange ? `Choose range, selected range is ${formattedRange}` : 'Choose range',
56
+ openRangePickerDialogue: formattedRange => formattedRange ? `λ²”μœ„λ₯Ό μ„ νƒν•˜μ„Έμš”. ν˜„μž¬ μ„ νƒλœ λ²”μœ„λŠ” ${formattedRange}μž…λ‹ˆλ‹€.` : 'λ²”μœ„λ₯Ό μ„ νƒν•˜μ„Έμš”',
58
57
  fieldClearLabel: 'μ§€μš°κΈ°',
59
58
  // Table labels
60
59
  timeTableLabel: 'μ„ νƒν•œ μ‹œκ°„',
@@ -76,8 +75,7 @@ const koKRPickers = {
76
75
  hours: 'μ‹œκ°„',
77
76
  minutes: 'λΆ„',
78
77
  seconds: '초',
79
- // meridiem: 'Meridiem',
80
-
78
+ meridiem: 'μ˜€μ „/μ˜€ν›„',
81
79
  // Common
82
80
  empty: 'κ³΅λž€'
83
81
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-date-pickers",
3
- "version": "8.9.0",
3
+ "version": "8.9.2",
4
4
  "author": "MUI Team",
5
5
  "description": "The community edition of the MUI X Date and Time Picker components.",
6
6
  "main": "./index.js",
@@ -15,8 +15,7 @@
15
15
  },
16
16
  "sideEffects": false,
17
17
  "publishConfig": {
18
- "access": "public",
19
- "directory": "build"
18
+ "access": "public"
20
19
  },
21
20
  "keywords": [
22
21
  "react",
@@ -35,13 +34,13 @@
35
34
  "directory": "packages/x-date-pickers"
36
35
  },
37
36
  "dependencies": {
38
- "@babel/runtime": "^7.27.6",
37
+ "@babel/runtime": "^7.28.2",
39
38
  "@mui/utils": "^7.2.0",
40
39
  "@types/react-transition-group": "^4.4.12",
41
40
  "clsx": "^2.1.1",
42
41
  "prop-types": "^15.8.1",
43
42
  "react-transition-group": "^4.4.5",
44
- "@mui/x-internals": "8.8.0"
43
+ "@mui/x-internals": "8.9.2"
45
44
  },
46
45
  "peerDependencies": {
47
46
  "@emotion/react": "^11.9.0",