@mui/x-date-pickers-pro 9.0.2 → 9.0.3

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
@@ -1,5 +1,141 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.0.3
4
+
5
+ _Apr 27, 2026_
6
+
7
+ We'd like to extend a big thank you to the 16 contributors who made this release possible. Here are some highlights ✨:
8
+
9
+ - ⌨️ Keyboard support for creating events in the Scheduler
10
+
11
+ Special thanks go out to these community members for their valuable contributions:
12
+ @supunsathsara, @ZAKIURREHMAN
13
+
14
+ The following team members contributed to this release:
15
+ @aemartos, @alexfauquette, @arminmeh, @brijeshb42, @Janpot, @JCQuintas, @LukasTy, @MBilalShafi, @michelengelen, @oliviertassinari, @rita-codes, @romgrk, @sai6855, @siriwatknp
16
+
17
+ ### Data Grid
18
+
19
+ #### `@mui/x-data-grid@9.0.3`
20
+
21
+ - [DataGrid] Fix `:first-child` SSR warning when `MuiDataGrid.styleOverrides` is set (#22081) @siriwatknp
22
+ - [DataGrid] Fix row reordering when filter hides rows (#22096) @siriwatknp
23
+ - [DataGrid] Remove unused `LayoutDataGridLegacy` class (#22009) @romgrk
24
+ - [DataGrid] Remove unused code, clean up grid-related utilities and deprecate `GridPanelHeader` (#22112) @sai6855
25
+ - [DataGrid] Fix columns cutting off after resizing (#22088) @ZAKIURREHMAN
26
+
27
+ #### `@mui/x-data-grid-pro@9.0.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
28
+
29
+ Same changes as in `@mui/x-data-grid@9.0.3`.
30
+
31
+ #### `@mui/x-data-grid-premium@9.0.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
32
+
33
+ Same changes as in `@mui/x-data-grid-pro@9.0.3`, plus:
34
+
35
+ - [DataGridPremium] Fix row grouping model updates not being reflected (#22122) @MBilalShafi
36
+
37
+ ### Date and Time Pickers
38
+
39
+ #### `@mui/x-date-pickers@9.0.3`
40
+
41
+ - [pickers] Fix `DateRangeCalendar` drag with `AdapterDayjs` plain-constructor values (#22165) @LukasTy
42
+ - [pickers] Fix disabled state not overriding error border color (#21169) @supunsathsara
43
+ - [pickers] Forward `data-*` and `aria-*` attributes to the root (#22147) @LukasTy
44
+ - [pickers] Support `K` and `k` hour format tokens (#22108) @michelengelen
45
+
46
+ #### `@mui/x-date-pickers-pro@9.0.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
47
+
48
+ Same changes as in `@mui/x-date-pickers@9.0.3`, plus:
49
+
50
+ - [DateRangeCalendar] Ensure date dragging triggers regardless of trigger element (#21868) @michelengelen
51
+
52
+ ### Charts
53
+
54
+ #### `@mui/x-charts@9.0.3`
55
+
56
+ - [charts] Centralize WebGL clear/render cycle (context-based) (#22127) @JCQuintas
57
+ - [charts] Fix closest series detection for line charts (#22168) @alexfauquette
58
+ - [charts] Fix radius grid lines when axis uses point scale (#22134) @alexfauquette
59
+ - [charts] Use cubic solver for berzier intersection (#22152) @alexfauquette
60
+
61
+ #### `@mui/x-charts-pro@9.0.3` [![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-charts@9.0.3`, plus:
64
+
65
+ - [charts-pro] Fix wheel zoom clamping with custom `minStart`/`maxEnd` (#22159) @JCQuintas
66
+
67
+ #### `@mui/x-charts-premium@9.0.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
68
+
69
+ Same changes as in `@mui/x-charts-pro@9.0.3`, plus:
70
+
71
+ - [charts] Create a `'radialLine'` series type (#22066) @alexfauquette
72
+ - [charts] Plot radial line (#22133) @alexfauquette
73
+ - [charts] Remove `HeatmapWebGLRenderer` indirection (#22169) @JCQuintas
74
+
75
+ ### Tree View
76
+
77
+ #### `@mui/x-tree-view@9.0.2`
78
+
79
+ Internal changes.
80
+
81
+ #### `@mui/x-tree-view-pro@9.0.2` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
82
+
83
+ Same changes as in `@mui/x-tree-view@9.0.2`.
84
+
85
+ ### Scheduler
86
+
87
+ #### Breaking changes
88
+
89
+ - The `views` of `EventTimelinePremium` have been renamed to `presets`, with names that describe the header layout. The props `view`/`defaultView`/`views`/`onViewChange` are now `preset`/`defaultPreset`/`presets`/`onPresetChange`, and the type `EventTimelinePremiumView` is now `EventTimelinePremiumPreset`.
90
+
91
+ | Old | New |
92
+ | :------- | :------------- |
93
+ | `time` | `dayAndHour` |
94
+ | `days` | `day` |
95
+ | `weeks` | `dayAndWeek` |
96
+ | `months` | `monthAndYear` |
97
+ | `years` | `year` |
98
+
99
+ CSS variables (`--time-cell-width`, etc.) and headless store state (`state.view`, `setView`) follow the same rename. The `presets` array is now sorted internally against a canonical zoom order.
100
+
101
+ #### `@mui/x-scheduler@9.0.0-alpha.3`
102
+
103
+ - [scheduler] Allow creating events via keyboard - EventCalendar (#21967) @rita-codes
104
+ - [scheduler] Prefix element IDs with a unique Scheduler instance ID (#22109) @rita-codes
105
+
106
+ #### `@mui/x-scheduler-premium@9.0.0-alpha.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
107
+
108
+ Same changes as in `@mui/x-scheduler@9.0.0-alpha.3`.
109
+
110
+ - [scheduler] Allow creating events via keyboard - `EventTimeline` (#22119) @rita-codes
111
+ - [scheduler] Rename `EventTimeline` `views` to ordered presets (#22130) @rita-codes
112
+
113
+ ### Docs
114
+
115
+ - [docs] Cleanup generated llm md files for chat (#22163) @brijeshb42
116
+ - [docs] Fix `highlightScope` description (#22154) @alexfauquette
117
+ - [docs] Remove obsolete v7 deprecation warning for `dayOfWeekFormatter` (#22111) @LukasTy
118
+ - [docs] Use mui.com for broken links checker known targets (#22129) @JCQuintas
119
+ - [docs] Document picker behavior inside MUI `Dialog` and provide recommended solutions (#22144) @michelengelen
120
+ - [docs] Improve v9 license key version mismatch error guidance (#22180) @aemartos
121
+
122
+ ### Core
123
+
124
+ - [code-infra] Reduce concurrency for package build to 5 (#22115) @Janpot
125
+ - [code-infra] Rename `docsx` alias to `docs` (#22155) @brijeshb42
126
+ - [docs-infra] Remove monorepo dependency (#22025) @brijeshb42
127
+ - [docs-infra] Use latest published packages (#22086) @brijeshb42
128
+ - [test] Refactor Pickers tests to async user-event (#22043) @LukasTy
129
+ - [test] Remove redundant explicit `unmount()` calls from Pickers tests (#22118) @LukasTy
130
+
131
+ ### Miscellaneous
132
+
133
+ - [infra] Update `.gitignore` to exclude `.claude/worktrees` (#22145) @michelengelen
134
+ - [infra] Enable branch tracking when creating release branch (#22177) @michelengelen
135
+ - [license] Add MIT license to `x-virtualizer` package (#22164) @michelengelen
136
+ - [website] Fix outdated MUI logos (#22117) @oliviertassinari
137
+ - [internal] Try avoiding store update when virtualization is disabled (#22093) @arminmeh
138
+
3
139
  ## 9.0.2
4
140
 
5
141
  <!-- generated comparing v9.0.1..master -->
@@ -37,8 +37,8 @@ var _jsxRuntime = require("react/jsx-runtime");
37
37
  const _excluded = ["value", "defaultValue", "referenceDate", "onChange", "className", "classes", "disableFuture", "disablePast", "minDate", "maxDate", "shouldDisableDate", "reduceAnimations", "onMonthChange", "rangePosition", "defaultRangePosition", "onRangePositionChange", "calendars", "currentMonthCalendarPosition", "slots", "slotProps", "loading", "renderLoading", "disableHighlightToday", "focusedView", "onFocusedViewChange", "readOnly", "disabled", "showDaysOutsideCurrentMonth", "dayOfWeekFormatter", "disableAutoMonthSwitching", "autoFocus", "fixedWeekNumber", "disableDragEditing", "displayWeekNumber", "timezone", "availableRangePositions", "views", "view", "openTo", "onViewChange"],
38
38
  _excluded2 = ["isDragging", "rangeDragDay", "draggingDatePosition"];
39
39
  const packageInfo = {
40
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
41
- version: "9.0.2",
40
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
41
+ version: "9.0.3",
42
42
  name: 'x-date-pickers-pro'
43
43
  };
44
44
  const DateRangeCalendarRoot = (0, _styles.styled)('div', {
@@ -30,8 +30,8 @@ import { PickersRangeCalendarHeader } from "../PickersRangeCalendarHeader/index.
30
30
  import { useNullablePickerRangePositionContext } from "../internals/hooks/useNullablePickerRangePositionContext.mjs";
31
31
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
32
32
  const packageInfo = {
33
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
34
- version: "9.0.2",
33
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
34
+ version: "9.0.3",
35
35
  name: 'x-date-pickers-pro'
36
36
  };
37
37
  const DateRangeCalendarRoot = styled('div', {
@@ -10,30 +10,91 @@ exports.useDragRange = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
  var React = _interopRequireWildcard(require("react"));
12
12
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
13
+ var _domUtils = require("@mui/x-internals/domUtils");
13
14
  var _dateUtils = require("../internals/utils/date-utils");
15
+ const isEnabledButtonElement = element => (0, _domUtils.isHTMLElement)(element) && element.tagName === 'BUTTON' && !element.disabled;
16
+ /**
17
+ * Finds the closest ancestor element (or the element itself) that has the specified data attribute.
18
+ * This is needed because drag/touch events can target child elements (e.g., text spans)
19
+ * inside the button, which don't have the data attributes directly.
20
+ *
21
+ * @param element The element to start searching from.
22
+ * @param dataAttribute The data attribute name — must be a single lowercase word
23
+ * (e.g., 'timestamp', 'position') because `dataset[attr]` uses camelCase
24
+ * while `.closest()` uses kebab-case, and these only align for single-word names.
25
+ */
26
+ const getClosestElementWithDataAttribute = (element, dataAttribute) => {
27
+ if (!element) {
28
+ return null;
29
+ }
30
+ return element.dataset[dataAttribute] != null ? element : element.closest(`[data-${dataAttribute}]`);
31
+ };
14
32
  const resolveDateFromTarget = (target, adapter, timezone) => {
15
- const timestampString = target.dataset.timestamp;
33
+ if (!(0, _domUtils.isHTMLElement)(target)) {
34
+ return null;
35
+ }
36
+ const element = getClosestElementWithDataAttribute(target, 'timestamp');
37
+ const timestampString = element?.dataset.timestamp;
16
38
  if (!timestampString) {
17
39
  return null;
18
40
  }
19
- const timestamp = +timestampString;
41
+ const timestamp = Number(timestampString);
20
42
  return adapter.date(new Date(timestamp).toISOString(), timezone);
21
43
  };
22
44
  const isSameAsDraggingDate = event => {
23
- const timestampString = event.target.dataset.timestamp;
24
- return timestampString === event.dataTransfer.getData('draggingDate');
45
+ const target = (0, _domUtils.getTarget)(event.nativeEvent);
46
+ if (!(0, _domUtils.isHTMLElement)(target)) {
47
+ return false;
48
+ }
49
+ const element = getClosestElementWithDataAttribute(target, 'timestamp');
50
+ return element?.dataset.timestamp === event.dataTransfer.getData('draggingDate');
25
51
  };
52
+
53
+ /**
54
+ * Resolves a button element from a given element.
55
+ * Searches both upward (ancestors) and downward (children) since:
56
+ * - Touch events may target child elements inside the button (e.g., TouchRipple)
57
+ * - `elementFromPoint` may return wrapper divs containing the button
58
+ */
26
59
  const resolveButtonElement = element => {
27
- if (element) {
28
- if (element instanceof HTMLButtonElement && !element.disabled) {
29
- return element;
60
+ if (!element) {
61
+ return null;
62
+ }
63
+
64
+ // Check if element itself is a valid button
65
+ if (isEnabledButtonElement(element)) {
66
+ return element;
67
+ }
68
+
69
+ // Search upward - element could be a child of the button (e.g., text span, TouchRipple)
70
+ const closestButton = element.closest('button');
71
+ if (isEnabledButtonElement(closestButton)) {
72
+ return closestButton;
73
+ }
74
+
75
+ // Search downward (breadth-first, max 3 levels) - element could be a wrapper containing the button.
76
+ // Day cells have shallow DOM, so a small depth limit keeps this efficient.
77
+ const queue = Array.from(element.children).map(el => ({
78
+ el,
79
+ depth: 1
80
+ }));
81
+ const maxDepth = 3;
82
+ while (queue.length > 0) {
83
+ const {
84
+ el: current,
85
+ depth
86
+ } = queue.shift();
87
+ if (isEnabledButtonElement(current)) {
88
+ return current;
30
89
  }
31
- if (element.children.length) {
32
- return resolveButtonElement(element.children[0]);
90
+ if (depth < maxDepth) {
91
+ queue.push(...Array.from(current.children).map(el => ({
92
+ el,
93
+ depth: depth + 1
94
+ })));
33
95
  }
34
- return null;
35
96
  }
36
- return element;
97
+ return null;
37
98
  };
38
99
  const resolveElementFromTouch = (event, ignoreTouchTarget) => {
39
100
  // don't parse multi-touch result
@@ -76,7 +137,7 @@ const useDragRangeEvents = ({
76
137
  return shouldInitDragging && (isSelectedStartDate || isSelectedEndDate);
77
138
  };
78
139
  const handleDragStart = (0, _useEventCallback.default)(event => {
79
- const newDate = resolveDateFromTarget(event.target, adapter, timezone);
140
+ const newDate = resolveDateFromTarget((0, _domUtils.getTarget)(event.nativeEvent), adapter, timezone);
80
141
  if (!isElementDraggable(newDate)) {
81
142
  return;
82
143
  }
@@ -87,11 +148,14 @@ const useDragRangeEvents = ({
87
148
  setRangeDragDay(newDate);
88
149
  event.dataTransfer.effectAllowed = 'move';
89
150
  setIsDragging(true);
90
- const buttonDataset = event.target.dataset;
91
- if (buttonDataset.timestamp) {
151
+ // Use currentTarget (the element the handler is attached to) rather than target
152
+ // because we need the button's dataset, not a potential child element's dataset.
153
+ const element = getClosestElementWithDataAttribute(event.currentTarget, 'timestamp');
154
+ const buttonDataset = element?.dataset;
155
+ if (buttonDataset?.timestamp) {
92
156
  event.dataTransfer.setData('draggingDate', buttonDataset.timestamp);
93
157
  }
94
- if (buttonDataset.position) {
158
+ if (buttonDataset?.position) {
95
159
  onDatePositionChange(buttonDataset.position);
96
160
  }
97
161
  });
@@ -113,7 +177,7 @@ const useDragRangeEvents = ({
113
177
  event.preventDefault();
114
178
  event.stopPropagation();
115
179
  event.dataTransfer.dropEffect = 'move';
116
- setRangeDragDay(resolveDateFromTarget(event.target, adapter, timezone));
180
+ setRangeDragDay(resolveDateFromTarget((0, _domUtils.getTarget)(event.nativeEvent), adapter, timezone));
117
181
  });
118
182
  const handleTouchMove = (0, _useEventCallback.default)(event => {
119
183
  const target = resolveElementFromTouch(event);
@@ -133,9 +197,12 @@ const useDragRangeEvents = ({
133
197
 
134
198
  // on mobile we should only initialize dragging state after move is detected
135
199
  setIsDragging(true);
136
- const button = event.target;
137
- const buttonDataset = button.dataset;
138
- if (buttonDataset.position) {
200
+
201
+ // Use currentTarget (the element the handler is attached to) rather than target
202
+ // because we need the button's dataset, not a potential child element's dataset.
203
+ const element = getClosestElementWithDataAttribute(event.currentTarget, 'position');
204
+ const buttonDataset = element?.dataset;
205
+ if (buttonDataset?.position) {
139
206
  onDatePositionChange(buttonDataset.position);
140
207
  }
141
208
  });
@@ -194,7 +261,7 @@ const useDragRangeEvents = ({
194
261
  if (isSameAsDraggingDate(event)) {
195
262
  return;
196
263
  }
197
- const newDate = resolveDateFromTarget(event.target, adapter, timezone);
264
+ const newDate = resolveDateFromTarget((0, _domUtils.getTarget)(event.nativeEvent), adapter, timezone);
198
265
  if (newDate) {
199
266
  onDrop(newDate);
200
267
  }
@@ -3,30 +3,91 @@
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import useEventCallback from '@mui/utils/useEventCallback';
6
+ import { getTarget, isHTMLElement } from '@mui/x-internals/domUtils';
6
7
  import { isEndOfRange, isStartOfRange } from "../internals/utils/date-utils.mjs";
8
+ const isEnabledButtonElement = element => isHTMLElement(element) && element.tagName === 'BUTTON' && !element.disabled;
9
+ /**
10
+ * Finds the closest ancestor element (or the element itself) that has the specified data attribute.
11
+ * This is needed because drag/touch events can target child elements (e.g., text spans)
12
+ * inside the button, which don't have the data attributes directly.
13
+ *
14
+ * @param element The element to start searching from.
15
+ * @param dataAttribute The data attribute name — must be a single lowercase word
16
+ * (e.g., 'timestamp', 'position') because `dataset[attr]` uses camelCase
17
+ * while `.closest()` uses kebab-case, and these only align for single-word names.
18
+ */
19
+ const getClosestElementWithDataAttribute = (element, dataAttribute) => {
20
+ if (!element) {
21
+ return null;
22
+ }
23
+ return element.dataset[dataAttribute] != null ? element : element.closest(`[data-${dataAttribute}]`);
24
+ };
7
25
  const resolveDateFromTarget = (target, adapter, timezone) => {
8
- const timestampString = target.dataset.timestamp;
26
+ if (!isHTMLElement(target)) {
27
+ return null;
28
+ }
29
+ const element = getClosestElementWithDataAttribute(target, 'timestamp');
30
+ const timestampString = element?.dataset.timestamp;
9
31
  if (!timestampString) {
10
32
  return null;
11
33
  }
12
- const timestamp = +timestampString;
34
+ const timestamp = Number(timestampString);
13
35
  return adapter.date(new Date(timestamp).toISOString(), timezone);
14
36
  };
15
37
  const isSameAsDraggingDate = event => {
16
- const timestampString = event.target.dataset.timestamp;
17
- return timestampString === event.dataTransfer.getData('draggingDate');
38
+ const target = getTarget(event.nativeEvent);
39
+ if (!isHTMLElement(target)) {
40
+ return false;
41
+ }
42
+ const element = getClosestElementWithDataAttribute(target, 'timestamp');
43
+ return element?.dataset.timestamp === event.dataTransfer.getData('draggingDate');
18
44
  };
45
+
46
+ /**
47
+ * Resolves a button element from a given element.
48
+ * Searches both upward (ancestors) and downward (children) since:
49
+ * - Touch events may target child elements inside the button (e.g., TouchRipple)
50
+ * - `elementFromPoint` may return wrapper divs containing the button
51
+ */
19
52
  const resolveButtonElement = element => {
20
- if (element) {
21
- if (element instanceof HTMLButtonElement && !element.disabled) {
22
- return element;
53
+ if (!element) {
54
+ return null;
55
+ }
56
+
57
+ // Check if element itself is a valid button
58
+ if (isEnabledButtonElement(element)) {
59
+ return element;
60
+ }
61
+
62
+ // Search upward - element could be a child of the button (e.g., text span, TouchRipple)
63
+ const closestButton = element.closest('button');
64
+ if (isEnabledButtonElement(closestButton)) {
65
+ return closestButton;
66
+ }
67
+
68
+ // Search downward (breadth-first, max 3 levels) - element could be a wrapper containing the button.
69
+ // Day cells have shallow DOM, so a small depth limit keeps this efficient.
70
+ const queue = Array.from(element.children).map(el => ({
71
+ el,
72
+ depth: 1
73
+ }));
74
+ const maxDepth = 3;
75
+ while (queue.length > 0) {
76
+ const {
77
+ el: current,
78
+ depth
79
+ } = queue.shift();
80
+ if (isEnabledButtonElement(current)) {
81
+ return current;
23
82
  }
24
- if (element.children.length) {
25
- return resolveButtonElement(element.children[0]);
83
+ if (depth < maxDepth) {
84
+ queue.push(...Array.from(current.children).map(el => ({
85
+ el,
86
+ depth: depth + 1
87
+ })));
26
88
  }
27
- return null;
28
89
  }
29
- return element;
90
+ return null;
30
91
  };
31
92
  const resolveElementFromTouch = (event, ignoreTouchTarget) => {
32
93
  // don't parse multi-touch result
@@ -69,7 +130,7 @@ const useDragRangeEvents = ({
69
130
  return shouldInitDragging && (isSelectedStartDate || isSelectedEndDate);
70
131
  };
71
132
  const handleDragStart = useEventCallback(event => {
72
- const newDate = resolveDateFromTarget(event.target, adapter, timezone);
133
+ const newDate = resolveDateFromTarget(getTarget(event.nativeEvent), adapter, timezone);
73
134
  if (!isElementDraggable(newDate)) {
74
135
  return;
75
136
  }
@@ -80,11 +141,14 @@ const useDragRangeEvents = ({
80
141
  setRangeDragDay(newDate);
81
142
  event.dataTransfer.effectAllowed = 'move';
82
143
  setIsDragging(true);
83
- const buttonDataset = event.target.dataset;
84
- if (buttonDataset.timestamp) {
144
+ // Use currentTarget (the element the handler is attached to) rather than target
145
+ // because we need the button's dataset, not a potential child element's dataset.
146
+ const element = getClosestElementWithDataAttribute(event.currentTarget, 'timestamp');
147
+ const buttonDataset = element?.dataset;
148
+ if (buttonDataset?.timestamp) {
85
149
  event.dataTransfer.setData('draggingDate', buttonDataset.timestamp);
86
150
  }
87
- if (buttonDataset.position) {
151
+ if (buttonDataset?.position) {
88
152
  onDatePositionChange(buttonDataset.position);
89
153
  }
90
154
  });
@@ -106,7 +170,7 @@ const useDragRangeEvents = ({
106
170
  event.preventDefault();
107
171
  event.stopPropagation();
108
172
  event.dataTransfer.dropEffect = 'move';
109
- setRangeDragDay(resolveDateFromTarget(event.target, adapter, timezone));
173
+ setRangeDragDay(resolveDateFromTarget(getTarget(event.nativeEvent), adapter, timezone));
110
174
  });
111
175
  const handleTouchMove = useEventCallback(event => {
112
176
  const target = resolveElementFromTouch(event);
@@ -126,9 +190,12 @@ const useDragRangeEvents = ({
126
190
 
127
191
  // on mobile we should only initialize dragging state after move is detected
128
192
  setIsDragging(true);
129
- const button = event.target;
130
- const buttonDataset = button.dataset;
131
- if (buttonDataset.position) {
193
+
194
+ // Use currentTarget (the element the handler is attached to) rather than target
195
+ // because we need the button's dataset, not a potential child element's dataset.
196
+ const element = getClosestElementWithDataAttribute(event.currentTarget, 'position');
197
+ const buttonDataset = element?.dataset;
198
+ if (buttonDataset?.position) {
132
199
  onDatePositionChange(buttonDataset.position);
133
200
  }
134
201
  });
@@ -187,7 +254,7 @@ const useDragRangeEvents = ({
187
254
  if (isSameAsDraggingDate(event)) {
188
255
  return;
189
256
  }
190
- const newDate = resolveDateFromTarget(event.target, adapter, timezone);
257
+ const newDate = resolveDateFromTarget(getTarget(event.nativeEvent), adapter, timezone);
191
258
  if (newDate) {
192
259
  onDrop(newDate);
193
260
  }
@@ -322,8 +322,8 @@ const DateRangePickerDayRaw = /*#__PURE__*/React.forwardRef(function DateRangePi
322
322
  name: 'MuiDateRangePickerDay'
323
323
  });
324
324
  (0, _internals.useLicenseVerifier)({
325
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
326
- version: "9.0.2",
325
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
326
+ version: "9.0.3",
327
327
  name: 'x-date-pickers-pro'
328
328
  });
329
329
  const adapter = (0, _hooks.usePickerAdapter)();
@@ -315,8 +315,8 @@ const DateRangePickerDayRaw = /*#__PURE__*/React.forwardRef(function DateRangePi
315
315
  name: 'MuiDateRangePickerDay'
316
316
  });
317
317
  useLicenseVerifier({
318
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
319
- version: "9.0.2",
318
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
319
+ version: "9.0.3",
320
320
  name: 'x-date-pickers-pro'
321
321
  });
322
322
  const adapter = usePickerAdapter();
@@ -31,7 +31,7 @@ MultiInputDateRangeField.propTypes = {
31
31
  // | To update them edit the TypeScript types and run "pnpm proptypes" |
32
32
  // ----------------------------------------------------------------------
33
33
  /**
34
- * If `true`, the `input` element is focused during the first mount.
34
+ * If `true`, the field is focused during the first mount.
35
35
  * @default false
36
36
  */
37
37
  autoFocus: _propTypes.default.bool,
@@ -27,7 +27,7 @@ MultiInputDateRangeField.propTypes = {
27
27
  // | To update them edit the TypeScript types and run "pnpm proptypes" |
28
28
  // ----------------------------------------------------------------------
29
29
  /**
30
- * If `true`, the `input` element is focused during the first mount.
30
+ * If `true`, the field is focused during the first mount.
31
31
  * @default false
32
32
  */
33
33
  autoFocus: PropTypes.bool,
@@ -36,7 +36,7 @@ MultiInputDateTimeRangeField.propTypes = {
36
36
  */
37
37
  ampm: _propTypes.default.bool,
38
38
  /**
39
- * If `true`, the `input` element is focused during the first mount.
39
+ * If `true`, the field is focused during the first mount.
40
40
  * @default false
41
41
  */
42
42
  autoFocus: _propTypes.default.bool,
@@ -32,7 +32,7 @@ MultiInputDateTimeRangeField.propTypes = {
32
32
  */
33
33
  ampm: PropTypes.bool,
34
34
  /**
35
- * If `true`, the `input` element is focused during the first mount.
35
+ * If `true`, the field is focused during the first mount.
36
36
  * @default false
37
37
  */
38
38
  autoFocus: PropTypes.bool,
@@ -37,7 +37,7 @@ MultiInputTimeRangeField.propTypes = {
37
37
  */
38
38
  ampm: _propTypes.default.bool,
39
39
  /**
40
- * If `true`, the `input` element is focused during the first mount.
40
+ * If `true`, the field is focused during the first mount.
41
41
  * @default false
42
42
  */
43
43
  autoFocus: _propTypes.default.bool,
@@ -33,7 +33,7 @@ MultiInputTimeRangeField.propTypes = {
33
33
  */
34
34
  ampm: PropTypes.bool,
35
35
  /**
36
- * If `true`, the `input` element is focused during the first mount.
36
+ * If `true`, the field is focused during the first mount.
37
37
  * @default false
38
38
  */
39
39
  autoFocus: PropTypes.bool,
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers-pro v9.0.2
2
+ * @mui/x-date-pickers-pro v9.0.3
3
3
  *
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  * This source code is licensed under the SEE LICENSE IN LICENSE license found in the
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers-pro v9.0.2
2
+ * @mui/x-date-pickers-pro v9.0.3
3
3
  *
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  * This source code is licensed under the SEE LICENSE IN LICENSE license found in the
@@ -26,8 +26,8 @@ const useDesktopRangePicker = _ref => {
26
26
  } = _ref,
27
27
  pickerParams = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
28
28
  (0, _internals.useLicenseVerifier)({
29
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
30
- version: "9.0.2",
29
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
30
+ version: "9.0.3",
31
31
  name: 'x-date-pickers-pro'
32
32
  });
33
33
  const {
@@ -64,6 +64,7 @@ const useDesktopRangePicker = _ref => {
64
64
  const _useSlotProps = (0, _useSlotProps2.default)({
65
65
  elementType: Field,
66
66
  externalSlotProps: slotProps?.field,
67
+ externalForwardedProps: (0, _internals2.extractRootForwardedProps)(props),
67
68
  ownerState,
68
69
  additionalProps: {
69
70
  'data-active-range-position': providerProps.contextValue.open ? rangePositionResponse.rangePosition : undefined
@@ -6,7 +6,7 @@ import useSlotProps from '@mui/utils/useSlotProps';
6
6
  import useEventCallback from '@mui/utils/useEventCallback';
7
7
  import { useLicenseVerifier } from '@mui/x-license/internals';
8
8
  import { PickersLayout } from '@mui/x-date-pickers/PickersLayout';
9
- import { usePicker, PickerPopper, PickerProvider } from '@mui/x-date-pickers/internals';
9
+ import { usePicker, PickerPopper, PickerProvider, extractRootForwardedProps } from '@mui/x-date-pickers/internals';
10
10
  import { useRangePosition } from "../useRangePosition.mjs";
11
11
  import { PickerRangePositionContext } from "../../../hooks/usePickerRangePositionContext.mjs";
12
12
  import { getRangeFieldType } from "../../utils/date-fields-utils.mjs";
@@ -19,8 +19,8 @@ export const useDesktopRangePicker = _ref => {
19
19
  } = _ref,
20
20
  pickerParams = _objectWithoutPropertiesLoose(_ref, _excluded);
21
21
  useLicenseVerifier({
22
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
23
- version: "9.0.2",
22
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
23
+ version: "9.0.3",
24
24
  name: 'x-date-pickers-pro'
25
25
  });
26
26
  const {
@@ -57,6 +57,7 @@ export const useDesktopRangePicker = _ref => {
57
57
  const _useSlotProps = useSlotProps({
58
58
  elementType: Field,
59
59
  externalSlotProps: slotProps?.field,
60
+ externalForwardedProps: extractRootForwardedProps(props),
60
61
  ownerState,
61
62
  additionalProps: {
62
63
  'data-active-range-position': providerProps.contextValue.open ? rangePositionResponse.rangePosition : undefined
@@ -28,8 +28,8 @@ const useMobileRangePicker = _ref => {
28
28
  } = _ref,
29
29
  pickerParams = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
30
30
  (0, _internals.useLicenseVerifier)({
31
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
32
- version: "9.0.2",
31
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
32
+ version: "9.0.3",
33
33
  name: 'x-date-pickers-pro'
34
34
  });
35
35
  const {
@@ -66,6 +66,7 @@ const useMobileRangePicker = _ref => {
66
66
  const _useSlotProps = (0, _useSlotProps2.default)({
67
67
  elementType: Field,
68
68
  externalSlotProps: innerSlotProps?.field,
69
+ externalForwardedProps: (0, _internals2.extractRootForwardedProps)(props),
69
70
  additionalProps: (0, _extends2.default)({}, isSingleInput && isToolbarHidden && {
70
71
  id: labelId
71
72
  }),
@@ -7,7 +7,7 @@ import useEventCallback from '@mui/utils/useEventCallback';
7
7
  import resolveComponentProps from '@mui/utils/resolveComponentProps';
8
8
  import { useLicenseVerifier } from '@mui/x-license/internals';
9
9
  import { PickersLayout } from '@mui/x-date-pickers/PickersLayout';
10
- import { usePicker, PickersModalDialog, PickerProvider } from '@mui/x-date-pickers/internals';
10
+ import { usePicker, PickersModalDialog, PickerProvider, extractRootForwardedProps } from '@mui/x-date-pickers/internals';
11
11
  import { usePickerTranslations } from '@mui/x-date-pickers/hooks';
12
12
  import { useRangePosition } from "../useRangePosition.mjs";
13
13
  import { PickerRangePositionContext } from "../../../hooks/usePickerRangePositionContext.mjs";
@@ -21,8 +21,8 @@ export const useMobileRangePicker = _ref => {
21
21
  } = _ref,
22
22
  pickerParams = _objectWithoutPropertiesLoose(_ref, _excluded);
23
23
  useLicenseVerifier({
24
- releaseDate: "MTc3NjIxMTIwMDAwMA==",
25
- version: "9.0.2",
24
+ releaseDate: "MTc3NzI0ODAwMDAwMA==",
25
+ version: "9.0.3",
26
26
  name: 'x-date-pickers-pro'
27
27
  });
28
28
  const {
@@ -59,6 +59,7 @@ export const useMobileRangePicker = _ref => {
59
59
  const _useSlotProps = useSlotProps({
60
60
  elementType: Field,
61
61
  externalSlotProps: innerSlotProps?.field,
62
+ externalForwardedProps: extractRootForwardedProps(props),
62
63
  additionalProps: _extends({}, isSingleInput && isToolbarHidden && {
63
64
  id: labelId
64
65
  }),
@@ -64,7 +64,7 @@ const useStaticRangePicker = _ref => {
64
64
  const renderPicker = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_usePickerRangePositionContext.PickerRangePositionContext.Provider, {
65
65
  value: rangePositionResponse,
66
66
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.PickerProvider, (0, _extends2.default)({}, providerProps, {
67
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Layout, (0, _extends2.default)({}, slotProps?.layout, {
67
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Layout, (0, _extends2.default)({}, (0, _internals.extractRootForwardedProps)(props), slotProps?.layout, {
68
68
  slots: slots,
69
69
  slotProps: slotProps,
70
70
  sx: (0, _internals.mergeSx)(providerProps.contextValue.rootSx, slotProps?.layout?.sx),
@@ -6,7 +6,7 @@ const _excluded = ["props", "steps"];
6
6
  import clsx from 'clsx';
7
7
  import { styled } from '@mui/material/styles';
8
8
  import { PickersLayout } from '@mui/x-date-pickers/PickersLayout';
9
- import { usePicker, DIALOG_WIDTH, PickerProvider, mergeSx } from '@mui/x-date-pickers/internals';
9
+ import { usePicker, DIALOG_WIDTH, PickerProvider, extractRootForwardedProps, mergeSx } from '@mui/x-date-pickers/internals';
10
10
  import { useRangePosition } from "../useRangePosition.mjs";
11
11
  import { PickerRangePositionContext } from "../../../hooks/usePickerRangePositionContext.mjs";
12
12
  import { createRangePickerStepNavigation } from "../../utils/createRangePickerStepNavigation.mjs";
@@ -58,7 +58,7 @@ export const useStaticRangePicker = _ref => {
58
58
  const renderPicker = () => /*#__PURE__*/_jsx(PickerRangePositionContext.Provider, {
59
59
  value: rangePositionResponse,
60
60
  children: /*#__PURE__*/_jsx(PickerProvider, _extends({}, providerProps, {
61
- children: /*#__PURE__*/_jsx(Layout, _extends({}, slotProps?.layout, {
61
+ children: /*#__PURE__*/_jsx(Layout, _extends({}, extractRootForwardedProps(props), slotProps?.layout, {
62
62
  slots: slots,
63
63
  slotProps: slotProps,
64
64
  sx: mergeSx(providerProps.contextValue.rootSx, slotProps?.layout?.sx),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-date-pickers-pro",
3
- "version": "9.0.2",
3
+ "version": "9.0.3",
4
4
  "author": "MUI Team",
5
5
  "description": "The Pro plan edition of the MUI X Date and Time Picker components.",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -30,14 +30,14 @@
30
30
  "directory": "packages/x-date-pickers-pro"
31
31
  },
32
32
  "dependencies": {
33
- "@babel/runtime": "^7.28.6",
33
+ "@babel/runtime": "^7.29.2",
34
34
  "@mui/utils": "9.0.0",
35
35
  "clsx": "^2.1.1",
36
36
  "prop-types": "^15.8.1",
37
37
  "react-transition-group": "^4.4.5",
38
- "@mui/x-date-pickers": "^9.0.2",
38
+ "@mui/x-internals": "^9.0.0",
39
39
  "@mui/x-license": "^9.0.2",
40
- "@mui/x-internals": "^9.0.0"
40
+ "@mui/x-date-pickers": "^9.0.3"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@emotion/react": "^11.9.0",