@mui/x-date-pickers 8.0.0-alpha.10 → 8.0.0-alpha.11
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 +107 -2
- package/DateCalendar/DateCalendar.js +37 -18
- package/DateCalendar/DayCalendar.d.ts +1 -2
- package/DateCalendar/DayCalendar.js +10 -36
- package/DateCalendar/useCalendarState.d.ts +8 -24
- package/DateCalendar/useCalendarState.js +65 -55
- package/PickersCalendarHeader/PickersCalendarHeader.js +2 -2
- package/PickersCalendarHeader/PickersCalendarHeader.types.d.ts +1 -2
- package/PickersTextField/PickersInputBase/PickersInputBase.js +2 -1
- package/index.js +1 -1
- package/modern/DateCalendar/DateCalendar.js +37 -18
- package/modern/DateCalendar/DayCalendar.js +10 -36
- package/modern/DateCalendar/useCalendarState.js +65 -55
- package/modern/PickersCalendarHeader/PickersCalendarHeader.js +2 -2
- package/modern/PickersTextField/PickersInputBase/PickersInputBase.js +2 -1
- package/modern/index.js +1 -1
- package/node/DateCalendar/DateCalendar.js +37 -18
- package/node/DateCalendar/DayCalendar.js +11 -37
- package/node/DateCalendar/useCalendarState.js +66 -57
- package/node/PickersCalendarHeader/PickersCalendarHeader.js +2 -2
- package/node/PickersTextField/PickersInputBase/PickersInputBase.js +2 -1
- package/node/index.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,110 @@
|
|
|
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.0.0-alpha.11**
|
|
9
|
+
|
|
10
|
+
_Feb 7, 2025_
|
|
11
|
+
|
|
12
|
+
We'd like to offer a big thanks to the 11 contributors who made this release possible. Here are some highlights ✨:
|
|
13
|
+
|
|
14
|
+
- ⚡ Mount and resize performance improvements for the Data Grid
|
|
15
|
+
|
|
16
|
+
Special thanks go out to the community contributors who have helped make this release possible:
|
|
17
|
+
@lauri865.
|
|
18
|
+
Following are all team members who have contributed to this release:
|
|
19
|
+
@alexfauquette, @arminmeh, @bernardobelchior, @flaviendelangle, @Janpot, @KenanYusuf, @LukasTy, @MBilalShafi, @noraleonte, @romgrk.
|
|
20
|
+
|
|
21
|
+
<!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
|
|
22
|
+
|
|
23
|
+
### Data Grid
|
|
24
|
+
|
|
25
|
+
#### Breaking changes
|
|
26
|
+
|
|
27
|
+
- `createUseGridApiEventHandler()` is not exported anymore.
|
|
28
|
+
- The `filteredRowsLookup` object of the filter state does not contain `true` values anymore. If the row is filtered out, the value is `false`. Otherwise, the row id is not present in the object.
|
|
29
|
+
This change only impacts you if you relied on `filteredRowsLookup` to get ids of filtered rows. In this case,use `gridDataRowIdsSelector` selector to get row ids and check `filteredRowsLookup` for `false` values:
|
|
30
|
+
|
|
31
|
+
```diff
|
|
32
|
+
const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
|
|
33
|
+
-const filteredRowIds = Object.keys(filteredRowsLookup).filter((rowId) => filteredRowsLookup[rowId] === true);
|
|
34
|
+
+const rowIds = gridDataRowIdsSelector(apiRef);
|
|
35
|
+
+const filteredRowIds = rowIds.filter((rowId) => filteredRowsLookup[rowId] !== false);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- The `visibleRowsLookup` state does not contain `true` values anymore. If the row is not visible, the value is `false`. Otherwise, the row id is not present in the object:
|
|
39
|
+
|
|
40
|
+
```diff
|
|
41
|
+
const visibleRowsLookup = gridVisibleRowsLookupSelector(apiRef);
|
|
42
|
+
-const isRowVisible = visibleRowsLookup[rowId] === true;
|
|
43
|
+
+const isRowVisible = visibleRowsLookup[rowId] !== false;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### `@mui/x-data-grid@8.0.0-alpha.11`
|
|
47
|
+
|
|
48
|
+
- [DataGrid] Avoid `<GridRoot />` double-render pass on mount in SPA mode (#15648) @lauri865
|
|
49
|
+
- [DataGrid] Fix loading overlay not in sync with scroll (#16437) @MBilalShafi
|
|
50
|
+
- [DataGrid] Refactor: remove material `MenuList` import (#16444) @romgrk
|
|
51
|
+
- [DataGrid] Refactor: simplify `useGridApiEventHandler()` (#16479) @romgrk
|
|
52
|
+
|
|
53
|
+
#### `@mui/x-data-grid-pro@8.0.0-alpha.11` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
54
|
+
|
|
55
|
+
Same changes as in `@mui/x-data-grid@8.0.0-alpha.11`, plus:
|
|
56
|
+
|
|
57
|
+
- [DataGridPro] Fix the return type of `useGridApiContext()` for Pro and Premium packages on React < 19 (#16441) @arminmeh
|
|
58
|
+
|
|
59
|
+
#### `@mui/x-data-grid-premium@8.0.0-alpha.11` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
60
|
+
|
|
61
|
+
Same changes as in `@mui/x-data-grid-pro@8.0.0-alpha.11`, plus:
|
|
62
|
+
|
|
63
|
+
- [DataGridPremium] Fix "no rows" overlay not showing with active aggregation (#16466) @KenanYusuf
|
|
64
|
+
|
|
65
|
+
### Date and Time Pickers
|
|
66
|
+
|
|
67
|
+
#### `@mui/x-date-pickers@8.0.0-alpha.11`
|
|
68
|
+
|
|
69
|
+
Internal changes.
|
|
70
|
+
|
|
71
|
+
#### `@mui/x-date-pickers-pro@8.0.0-alpha.11` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
72
|
+
|
|
73
|
+
Same changes as in `@mui/x-date-pickers@8.0.0-alpha.11`, plus:
|
|
74
|
+
|
|
75
|
+
- [DateRangeCalendar] Support arrow navigation with multiple months rendered (#16363) @flaviendelangle
|
|
76
|
+
- [DateRangePicker] Fix `currentMonthCalendarPosition` prop behavior on mobile (#16455) @LukasTy
|
|
77
|
+
- [DateRangePicker] Fix vertical alignment for multi input fields (#16489) @noraleonte
|
|
78
|
+
|
|
79
|
+
### Charts
|
|
80
|
+
|
|
81
|
+
#### `@mui/x-charts@8.0.0-alpha.11`
|
|
82
|
+
|
|
83
|
+
- [charts] Add `color` prop to `Sparkline` and deprecate `colors` (#16477) @bernardobelchior
|
|
84
|
+
- [charts] Make typescript more flexible about plugins and their params (#16478) @alexfauquette
|
|
85
|
+
- [charts] Remove component for axis event listener (#16314) @alexfauquette
|
|
86
|
+
|
|
87
|
+
#### `@mui/x-charts-pro@8.0.0-alpha.11` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
88
|
+
|
|
89
|
+
Same changes as in `@mui/x-charts@8.0.0-alpha.11`.
|
|
90
|
+
|
|
91
|
+
### Tree View
|
|
92
|
+
|
|
93
|
+
#### `@mui/x-tree-view@8.0.0-alpha.11`
|
|
94
|
+
|
|
95
|
+
Internal changes.
|
|
96
|
+
|
|
97
|
+
#### `@mui/x-tree-view-pro@8.0.0-alpha.11` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
98
|
+
|
|
99
|
+
Same changes as in `@mui/x-tree-view@8.0.0-alpha.11`.
|
|
100
|
+
|
|
101
|
+
### Docs
|
|
102
|
+
|
|
103
|
+
- [docs] Update charts colors default value (#16484) @bernardobelchior
|
|
104
|
+
|
|
105
|
+
### Core
|
|
106
|
+
|
|
107
|
+
- [core] Fix corepack and pnpm installation in CircleCI (#16434) @flaviendelangle
|
|
108
|
+
- [code-infra] Update monorepo (#16112) @Janpot
|
|
109
|
+
- [test] Avoid test warning when running on React 18 (#16486) @LukasTy
|
|
110
|
+
- [test] Disable `react-transition-group` transitions in unit testing (#16288) @lauri865
|
|
111
|
+
|
|
8
112
|
## 8.0.0-alpha.10
|
|
9
113
|
|
|
10
114
|
_Jan 30, 2025_
|
|
@@ -50,6 +154,7 @@ Following are all team members who have contributed to this release:
|
|
|
50
154
|
+ },
|
|
51
155
|
});
|
|
52
156
|
```
|
|
157
|
+
|
|
53
158
|
- The `detailPanels`, `pinnedColumns`, and `pinnedRowsRenderZone` classes have been removed.
|
|
54
159
|
- Return type of the `useGridApiRef()` hook and the type of `apiRef` prop are updated to explicitly include the possibilty of `null`. In addition to this, `useGridApiRef()` returns a reference that is initialized with `null` instead of `{}`.
|
|
55
160
|
|
|
@@ -91,7 +196,7 @@ Same changes as in `@mui/x-data-grid-pro@8.0.0-alpha.10`.
|
|
|
91
196
|
|
|
92
197
|
#### Breaking changes
|
|
93
198
|
|
|
94
|
-
- The component passed to the `field` slot no longer receives the `ref`,
|
|
199
|
+
- The component passed to the `field` slot no longer receives the `ref`, `disabled`, `className`, `sx`, `label`, `name`, `formatDensity`, `enableAccessibleFieldDOMStructure`, `selectedSections`, `onSelectedSectionsChange` and `inputRef` props — [Learn more](https://next.mui.com/x/migration/migration-pickers-v7/#slot-field)
|
|
95
200
|
- The `MuiPickersPopper` theme entry have been renamed `MuiPickerPopper` and some of its props have been removed — [Learn more](https://next.mui.com/x/migration/migration-pickers-v7/#muipickerspopper)
|
|
96
201
|
|
|
97
202
|
#### `@mui/x-date-pickers@8.0.0-alpha.10`
|
|
@@ -111,7 +216,7 @@ Same changes as in `@mui/x-date-pickers@8.0.0-alpha.10`.
|
|
|
111
216
|
|
|
112
217
|
- Replace `legend.position.horizontal` from `"left" | "middle" | "right"` to `"start" | "center" | "end"`.
|
|
113
218
|
This is to align with the CSS values and reflect the RTL ability of the legend component.
|
|
114
|
-
- The default colors have changed. To keep using the old palette. It is possible to import `blueberryTwilightPalette` from
|
|
219
|
+
- The default colors have changed. To keep using the old palette. It is possible to import `blueberryTwilightPalette` from `@mui/x-charts/colorPalettes` and set it on the `colors` property of charts.
|
|
115
220
|
- The `id` property is now optional on the `Pie` and `Scatter` data types.
|
|
116
221
|
|
|
117
222
|
#### `@mui/x-charts@8.0.0-alpha.10`
|
|
@@ -96,7 +96,6 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
96
96
|
disableFuture,
|
|
97
97
|
disablePast,
|
|
98
98
|
onChange,
|
|
99
|
-
onYearChange,
|
|
100
99
|
onMonthChange,
|
|
101
100
|
reduceAnimations,
|
|
102
101
|
shouldDisableDate,
|
|
@@ -112,7 +111,7 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
112
111
|
minDate,
|
|
113
112
|
maxDate,
|
|
114
113
|
disableHighlightToday,
|
|
115
|
-
focusedView:
|
|
114
|
+
focusedView: focusedViewProp,
|
|
116
115
|
onFocusedViewChange,
|
|
117
116
|
showDaysOutsideCurrentMonth,
|
|
118
117
|
fixedWeekNumber,
|
|
@@ -155,15 +154,13 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
155
154
|
onChange: handleValueChange,
|
|
156
155
|
onViewChange,
|
|
157
156
|
autoFocus,
|
|
158
|
-
focusedView:
|
|
157
|
+
focusedView: focusedViewProp,
|
|
159
158
|
onFocusedViewChange
|
|
160
159
|
});
|
|
161
160
|
const {
|
|
162
161
|
referenceDate,
|
|
163
162
|
calendarState,
|
|
164
|
-
|
|
165
|
-
changeMonth,
|
|
166
|
-
handleChangeMonth,
|
|
163
|
+
setVisibleDate,
|
|
167
164
|
isDateDisabled,
|
|
168
165
|
onMonthSwitchingAnimationEnd
|
|
169
166
|
} = useCalendarState({
|
|
@@ -176,7 +173,13 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
176
173
|
shouldDisableDate,
|
|
177
174
|
disablePast,
|
|
178
175
|
disableFuture,
|
|
179
|
-
timezone
|
|
176
|
+
timezone,
|
|
177
|
+
getCurrentMonthFromVisibleDate: (visibleDate, prevMonth) => {
|
|
178
|
+
if (utils.isSameMonth(visibleDate, prevMonth)) {
|
|
179
|
+
return prevMonth;
|
|
180
|
+
}
|
|
181
|
+
return utils.startOfMonth(visibleDate);
|
|
182
|
+
}
|
|
180
183
|
});
|
|
181
184
|
|
|
182
185
|
// When disabled, limit the view to the selected date
|
|
@@ -193,9 +196,9 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
193
196
|
view,
|
|
194
197
|
currentMonth: calendarState.currentMonth,
|
|
195
198
|
onViewChange: setView,
|
|
196
|
-
onMonthChange:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
onMonthChange: month => setVisibleDate({
|
|
200
|
+
target: month,
|
|
201
|
+
reason: 'header-navigation'
|
|
199
202
|
}),
|
|
200
203
|
minDate: minDateWithDisabled,
|
|
201
204
|
maxDate: maxDateWithDisabled,
|
|
@@ -223,12 +226,17 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
223
226
|
}) : newDate;
|
|
224
227
|
if (closestEnabledDate) {
|
|
225
228
|
setValueAndGoToNextView(closestEnabledDate, 'finish');
|
|
226
|
-
|
|
229
|
+
setVisibleDate({
|
|
230
|
+
target: closestEnabledDate,
|
|
231
|
+
reason: 'cell-interaction'
|
|
232
|
+
});
|
|
227
233
|
} else {
|
|
228
234
|
goToNextView();
|
|
229
|
-
|
|
235
|
+
setVisibleDate({
|
|
236
|
+
target: startOfMonth,
|
|
237
|
+
reason: 'cell-interaction'
|
|
238
|
+
});
|
|
230
239
|
}
|
|
231
|
-
changeFocusedDay(closestEnabledDate, true);
|
|
232
240
|
});
|
|
233
241
|
const handleDateYearChange = useEventCallback(newDate => {
|
|
234
242
|
const startOfYear = utils.startOfYear(newDate);
|
|
@@ -245,12 +253,17 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
245
253
|
}) : newDate;
|
|
246
254
|
if (closestEnabledDate) {
|
|
247
255
|
setValueAndGoToNextView(closestEnabledDate, 'finish');
|
|
248
|
-
|
|
256
|
+
setVisibleDate({
|
|
257
|
+
target: closestEnabledDate,
|
|
258
|
+
reason: 'cell-interaction'
|
|
259
|
+
});
|
|
249
260
|
} else {
|
|
250
261
|
goToNextView();
|
|
251
|
-
|
|
262
|
+
setVisibleDate({
|
|
263
|
+
target: startOfYear,
|
|
264
|
+
reason: 'cell-interaction'
|
|
265
|
+
});
|
|
252
266
|
}
|
|
253
|
-
changeFocusedDay(closestEnabledDate, true);
|
|
254
267
|
});
|
|
255
268
|
const handleSelectedDayChange = useEventCallback(day => {
|
|
256
269
|
if (day) {
|
|
@@ -261,7 +274,10 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
261
274
|
});
|
|
262
275
|
React.useEffect(() => {
|
|
263
276
|
if (utils.isValid(value)) {
|
|
264
|
-
|
|
277
|
+
setVisibleDate({
|
|
278
|
+
target: value,
|
|
279
|
+
reason: 'controlled-value-change'
|
|
280
|
+
});
|
|
265
281
|
}
|
|
266
282
|
}, [value]); // eslint-disable-line
|
|
267
283
|
|
|
@@ -328,7 +344,10 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
|
|
|
328
344
|
referenceDate: referenceDate
|
|
329
345
|
})), view === 'day' && /*#__PURE__*/_jsx(DayCalendar, _extends({}, calendarState, baseDateValidationProps, commonViewProps, {
|
|
330
346
|
onMonthSwitchingAnimationEnd: onMonthSwitchingAnimationEnd,
|
|
331
|
-
onFocusedDayChange:
|
|
347
|
+
onFocusedDayChange: focusedDate => setVisibleDate({
|
|
348
|
+
target: focusedDate,
|
|
349
|
+
reason: 'cell-interaction'
|
|
350
|
+
}),
|
|
332
351
|
reduceAnimations: reduceAnimations,
|
|
333
352
|
selectedDays: selectedDays,
|
|
334
353
|
onSelectedDaysChange: handleSelectedDayChange,
|
|
@@ -54,7 +54,6 @@ export interface ExportedDayCalendarProps extends ExportedPickersDayProps {
|
|
|
54
54
|
fixedWeekNumber?: number;
|
|
55
55
|
}
|
|
56
56
|
export interface DayCalendarProps extends ExportedDayCalendarProps, DayValidationProps, MonthValidationProps, YearValidationProps, Required<BaseDateValidationProps>, DefaultizedProps<TimezoneProps, 'timezone'>, FormProps {
|
|
57
|
-
autoFocus?: boolean;
|
|
58
57
|
className?: string;
|
|
59
58
|
currentMonth: PickerValidDate;
|
|
60
59
|
selectedDays: (PickerValidDate | null)[];
|
|
@@ -66,7 +65,7 @@ export interface DayCalendarProps extends ExportedDayCalendarProps, DayValidatio
|
|
|
66
65
|
reduceAnimations: boolean;
|
|
67
66
|
slideDirection: SlideDirection;
|
|
68
67
|
TransitionProps?: Partial<SlideTransitionProps>;
|
|
69
|
-
hasFocus
|
|
68
|
+
hasFocus: boolean;
|
|
70
69
|
onFocusedViewChange?: (newHasFocus: boolean) => void;
|
|
71
70
|
gridLabelId?: string;
|
|
72
71
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
4
4
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
5
|
-
const _excluded = ["parentProps", "day", "
|
|
5
|
+
const _excluded = ["parentProps", "day", "focusedDay", "selectedDays", "isDateDisabled", "currentMonthNumber", "isViewFocused"],
|
|
6
6
|
_excluded2 = ["ownerState"];
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import useEventCallback from '@mui/utils/useEventCallback';
|
|
@@ -10,7 +10,7 @@ import Typography from '@mui/material/Typography';
|
|
|
10
10
|
import useSlotProps from '@mui/utils/useSlotProps';
|
|
11
11
|
import { useRtl } from '@mui/system/RtlProvider';
|
|
12
12
|
import { styled, useThemeProps } from '@mui/material/styles';
|
|
13
|
-
import
|
|
13
|
+
import composeClasses from '@mui/utils/composeClasses';
|
|
14
14
|
import clsx from 'clsx';
|
|
15
15
|
import { PickersDay } from "../PickersDay/PickersDay.js";
|
|
16
16
|
import { usePickerTranslations } from "../hooks/usePickerTranslations.js";
|
|
@@ -137,7 +137,7 @@ function WrappedDay(_ref) {
|
|
|
137
137
|
let {
|
|
138
138
|
parentProps,
|
|
139
139
|
day,
|
|
140
|
-
|
|
140
|
+
focusedDay,
|
|
141
141
|
selectedDays,
|
|
142
142
|
isDateDisabled,
|
|
143
143
|
currentMonthNumber,
|
|
@@ -158,7 +158,8 @@ function WrappedDay(_ref) {
|
|
|
158
158
|
const {
|
|
159
159
|
ownerState
|
|
160
160
|
} = usePickerPrivateContext();
|
|
161
|
-
const isFocusableDay =
|
|
161
|
+
const isFocusableDay = focusedDay != null && utils.isSameDay(day, focusedDay);
|
|
162
|
+
const isFocusedDay = isViewFocused && isFocusableDay;
|
|
162
163
|
const isSelected = selectedDays.some(selectedDay => utils.isSameDay(selectedDay, day));
|
|
163
164
|
const isToday = utils.isSameDay(day, now);
|
|
164
165
|
const isDisabled = React.useMemo(() => disabled || isDateDisabled(day), [disabled, isDateDisabled, day]);
|
|
@@ -200,7 +201,7 @@ function WrappedDay(_ref) {
|
|
|
200
201
|
return /*#__PURE__*/_jsx(Day, _extends({}, dayProps, {
|
|
201
202
|
day: day,
|
|
202
203
|
disabled: isDisabled,
|
|
203
|
-
autoFocus:
|
|
204
|
+
autoFocus: !outsideCurrentMonth && isFocusedDay,
|
|
204
205
|
today: isToday,
|
|
205
206
|
outsideCurrentMonth: outsideCurrentMonth,
|
|
206
207
|
isFirstVisibleCell: isFirstVisibleCell,
|
|
@@ -251,7 +252,6 @@ export function DayCalendar(inProps) {
|
|
|
251
252
|
gridLabelId,
|
|
252
253
|
displayWeekNumber,
|
|
253
254
|
fixedWeekNumber,
|
|
254
|
-
autoFocus,
|
|
255
255
|
timezone
|
|
256
256
|
} = props;
|
|
257
257
|
const now = useNow(timezone);
|
|
@@ -268,13 +268,6 @@ export function DayCalendar(inProps) {
|
|
|
268
268
|
timezone
|
|
269
269
|
});
|
|
270
270
|
const translations = usePickerTranslations();
|
|
271
|
-
const [internalHasFocus, setInternalHasFocus] = useControlled({
|
|
272
|
-
name: 'DayCalendar',
|
|
273
|
-
state: 'hasFocus',
|
|
274
|
-
controlled: hasFocus,
|
|
275
|
-
default: autoFocus ?? false
|
|
276
|
-
});
|
|
277
|
-
const [internalFocusedDay, setInternalFocusedDay] = React.useState(() => focusedDay || now);
|
|
278
271
|
const handleDaySelect = useEventCallback(day => {
|
|
279
272
|
if (readOnly) {
|
|
280
273
|
return;
|
|
@@ -284,9 +277,7 @@ export function DayCalendar(inProps) {
|
|
|
284
277
|
const focusDay = day => {
|
|
285
278
|
if (!isDateDisabled(day)) {
|
|
286
279
|
onFocusedDayChange(day);
|
|
287
|
-
setInternalFocusedDay(day);
|
|
288
280
|
onFocusedViewChange?.(true);
|
|
289
|
-
setInternalHasFocus(true);
|
|
290
281
|
}
|
|
291
282
|
};
|
|
292
283
|
const handleKeyDown = useEventCallback((event, day) => {
|
|
@@ -353,7 +344,7 @@ export function DayCalendar(inProps) {
|
|
|
353
344
|
});
|
|
354
345
|
const handleFocus = useEventCallback((event, day) => focusDay(day));
|
|
355
346
|
const handleBlur = useEventCallback((event, day) => {
|
|
356
|
-
if (
|
|
347
|
+
if (focusedDay != null && utils.isSameDay(focusedDay, day)) {
|
|
357
348
|
onFocusedViewChange?.(false);
|
|
358
349
|
}
|
|
359
350
|
});
|
|
@@ -365,23 +356,6 @@ export function DayCalendar(inProps) {
|
|
|
365
356
|
const transitionKey = `${currentYearNumber}-${currentMonthNumber}`;
|
|
366
357
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
367
358
|
const slideNodeRef = React.useMemo(() => /*#__PURE__*/React.createRef(), [transitionKey]);
|
|
368
|
-
const focusableDay = React.useMemo(() => {
|
|
369
|
-
const startOfMonth = utils.startOfMonth(currentMonth);
|
|
370
|
-
const endOfMonth = utils.endOfMonth(currentMonth);
|
|
371
|
-
if (isDateDisabled(internalFocusedDay) || utils.isAfterDay(internalFocusedDay, endOfMonth) || utils.isBeforeDay(internalFocusedDay, startOfMonth)) {
|
|
372
|
-
return findClosestEnabledDate({
|
|
373
|
-
utils,
|
|
374
|
-
date: internalFocusedDay,
|
|
375
|
-
minDate: startOfMonth,
|
|
376
|
-
maxDate: endOfMonth,
|
|
377
|
-
disablePast,
|
|
378
|
-
disableFuture,
|
|
379
|
-
isDateDisabled,
|
|
380
|
-
timezone
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
return internalFocusedDay;
|
|
384
|
-
}, [currentMonth, disableFuture, disablePast, internalFocusedDay, isDateDisabled, utils, timezone]);
|
|
385
359
|
const weeksToDisplay = React.useMemo(() => {
|
|
386
360
|
const toDisplay = utils.getWeekArray(currentMonth);
|
|
387
361
|
let nextMonth = utils.addMonths(currentMonth, 1);
|
|
@@ -448,14 +422,14 @@ export function DayCalendar(inProps) {
|
|
|
448
422
|
parentProps: props,
|
|
449
423
|
day: day,
|
|
450
424
|
selectedDays: validSelectedDays,
|
|
451
|
-
|
|
425
|
+
isViewFocused: hasFocus,
|
|
426
|
+
focusedDay: focusedDay,
|
|
452
427
|
onKeyDown: handleKeyDown,
|
|
453
428
|
onFocus: handleFocus,
|
|
454
429
|
onBlur: handleBlur,
|
|
455
430
|
onDaySelect: handleDaySelect,
|
|
456
431
|
isDateDisabled: isDateDisabled,
|
|
457
|
-
currentMonthNumber: currentMonthNumber
|
|
458
|
-
isViewFocused: internalHasFocus
|
|
432
|
+
currentMonthNumber: currentMonthNumber
|
|
459
433
|
// fix issue of announcing column 1 as column 2 when `displayWeekNumber` is enabled
|
|
460
434
|
,
|
|
461
435
|
"aria-colindex": dayIndex + 1
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SlideDirection } from './PickersSlideTransition';
|
|
2
|
-
import {
|
|
2
|
+
import { PickersTimezone, PickerValidDate } from '../models';
|
|
3
3
|
import { DateCalendarDefaultizedProps } from './DateCalendar.types';
|
|
4
4
|
interface CalendarState {
|
|
5
5
|
currentMonth: PickerValidDate;
|
|
@@ -7,37 +7,21 @@ interface CalendarState {
|
|
|
7
7
|
isMonthSwitchingAnimating: boolean;
|
|
8
8
|
slideDirection: SlideDirection;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
type: TType;
|
|
12
|
-
} & TAdditional;
|
|
13
|
-
interface ChangeMonthPayload {
|
|
14
|
-
direction: SlideDirection;
|
|
15
|
-
newMonth: PickerValidDate;
|
|
16
|
-
}
|
|
17
|
-
interface ChangeFocusedDayPayload {
|
|
18
|
-
focusedDay: PickerValidDate | null;
|
|
19
|
-
/**
|
|
20
|
-
* The update does not trigger month switching animation.
|
|
21
|
-
* For example: when selecting month from the month view.
|
|
22
|
-
*/
|
|
23
|
-
withoutMonthSwitchingAnimation?: boolean;
|
|
24
|
-
}
|
|
25
|
-
export declare const createCalendarStateReducer: (reduceAnimations: boolean, disableSwitchToMonthOnDayFocus: boolean, utils: MuiPickersAdapter) => (state: CalendarState, action: ReducerAction<"finishMonthSwitchingAnimation"> | ReducerAction<"changeMonth", ChangeMonthPayload> | ReducerAction<"changeMonthTimezone", {
|
|
26
|
-
newTimezone: string;
|
|
27
|
-
}> | ReducerAction<"changeFocusedDay", ChangeFocusedDayPayload>) => CalendarState;
|
|
28
|
-
interface UseCalendarStateParameters extends Pick<DateCalendarDefaultizedProps, 'referenceDate' | 'disableFuture' | 'disablePast' | 'minDate' | 'maxDate' | 'onMonthChange' | 'reduceAnimations' | 'shouldDisableDate'> {
|
|
10
|
+
interface UseCalendarStateParameters extends Pick<DateCalendarDefaultizedProps, 'referenceDate' | 'disableFuture' | 'disablePast' | 'minDate' | 'maxDate' | 'onMonthChange' | 'onYearChange' | 'reduceAnimations' | 'shouldDisableDate'> {
|
|
29
11
|
value: PickerValidDate | null;
|
|
30
|
-
disableSwitchToMonthOnDayFocus?: boolean;
|
|
31
12
|
timezone: PickersTimezone;
|
|
13
|
+
getCurrentMonthFromVisibleDate: (focusedDay: PickerValidDate, prevMonth: PickerValidDate) => PickerValidDate;
|
|
32
14
|
}
|
|
33
15
|
interface UseCalendarStateReturnValue {
|
|
34
16
|
referenceDate: PickerValidDate;
|
|
35
17
|
calendarState: CalendarState;
|
|
36
|
-
|
|
37
|
-
changeFocusedDay: (newFocusedDate: PickerValidDate | null, withoutMonthSwitchingAnimation?: boolean) => void;
|
|
18
|
+
setVisibleDate: (parameters: SetVisibleDateParameters) => void;
|
|
38
19
|
isDateDisabled: (day: PickerValidDate | null) => boolean;
|
|
39
20
|
onMonthSwitchingAnimationEnd: () => void;
|
|
40
|
-
handleChangeMonth: (payload: ChangeMonthPayload) => void;
|
|
41
21
|
}
|
|
42
22
|
export declare const useCalendarState: (params: UseCalendarStateParameters) => UseCalendarStateReturnValue;
|
|
23
|
+
interface SetVisibleDateParameters {
|
|
24
|
+
target: PickerValidDate;
|
|
25
|
+
reason: 'header-navigation' | 'cell-interaction' | 'controlled-value-change';
|
|
26
|
+
}
|
|
43
27
|
export {};
|
|
@@ -7,13 +7,15 @@ import { useIsDateDisabled } from "./useIsDateDisabled.js";
|
|
|
7
7
|
import { useUtils } from "../internals/hooks/useUtils.js";
|
|
8
8
|
import { singleItemValueManager } from "../internals/utils/valueManagers.js";
|
|
9
9
|
import { SECTION_TYPE_GRANULARITY } from "../internals/utils/getDefaultReferenceDate.js";
|
|
10
|
-
|
|
10
|
+
import { findClosestEnabledDate } from "../internals/utils/date-utils.js";
|
|
11
|
+
const createCalendarStateReducer = (reduceAnimations, utils) => (state, action) => {
|
|
11
12
|
switch (action.type) {
|
|
12
|
-
case '
|
|
13
|
+
case 'setVisibleDate':
|
|
13
14
|
return _extends({}, state, {
|
|
14
15
|
slideDirection: action.direction,
|
|
15
|
-
currentMonth: action.
|
|
16
|
-
isMonthSwitchingAnimating: !reduceAnimations
|
|
16
|
+
currentMonth: action.month,
|
|
17
|
+
isMonthSwitchingAnimating: !utils.isSameMonth(action.month, state.currentMonth) && !reduceAnimations && !action.skipAnimation,
|
|
18
|
+
focusedDay: action.focusedDay
|
|
17
19
|
});
|
|
18
20
|
case 'changeMonthTimezone':
|
|
19
21
|
{
|
|
@@ -33,19 +35,6 @@ export const createCalendarStateReducer = (reduceAnimations, disableSwitchToMont
|
|
|
33
35
|
return _extends({}, state, {
|
|
34
36
|
isMonthSwitchingAnimating: false
|
|
35
37
|
});
|
|
36
|
-
case 'changeFocusedDay':
|
|
37
|
-
{
|
|
38
|
-
if (state.focusedDay != null && action.focusedDay != null && utils.isSameDay(action.focusedDay, state.focusedDay)) {
|
|
39
|
-
return state;
|
|
40
|
-
}
|
|
41
|
-
const needMonthSwitch = action.focusedDay != null && !disableSwitchToMonthOnDayFocus && !utils.isSameMonth(state.currentMonth, action.focusedDay);
|
|
42
|
-
return _extends({}, state, {
|
|
43
|
-
focusedDay: action.focusedDay,
|
|
44
|
-
isMonthSwitchingAnimating: needMonthSwitch && !reduceAnimations && !action.withoutMonthSwitchingAnimation,
|
|
45
|
-
currentMonth: needMonthSwitch ? utils.startOfMonth(action.focusedDay) : state.currentMonth,
|
|
46
|
-
slideDirection: action.focusedDay != null && utils.isAfterDay(action.focusedDay, state.currentMonth) ? 'left' : 'right'
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
38
|
default:
|
|
50
39
|
throw new Error('missing support');
|
|
51
40
|
}
|
|
@@ -56,16 +45,17 @@ export const useCalendarState = params => {
|
|
|
56
45
|
referenceDate: referenceDateProp,
|
|
57
46
|
disableFuture,
|
|
58
47
|
disablePast,
|
|
59
|
-
disableSwitchToMonthOnDayFocus = false,
|
|
60
48
|
maxDate,
|
|
61
49
|
minDate,
|
|
62
50
|
onMonthChange,
|
|
51
|
+
onYearChange,
|
|
63
52
|
reduceAnimations,
|
|
64
53
|
shouldDisableDate,
|
|
65
|
-
timezone
|
|
54
|
+
timezone,
|
|
55
|
+
getCurrentMonthFromVisibleDate
|
|
66
56
|
} = params;
|
|
67
57
|
const utils = useUtils();
|
|
68
|
-
const reducerFn = React.useRef(createCalendarStateReducer(Boolean(reduceAnimations),
|
|
58
|
+
const reducerFn = React.useRef(createCalendarStateReducer(Boolean(reduceAnimations), utils)).current;
|
|
69
59
|
const referenceDate = React.useMemo(() => {
|
|
70
60
|
return singleItemValueManager.getInitialReferenceValue({
|
|
71
61
|
value,
|
|
@@ -85,6 +75,14 @@ export const useCalendarState = params => {
|
|
|
85
75
|
currentMonth: utils.startOfMonth(referenceDate),
|
|
86
76
|
slideDirection: 'left'
|
|
87
77
|
});
|
|
78
|
+
const isDateDisabled = useIsDateDisabled({
|
|
79
|
+
shouldDisableDate,
|
|
80
|
+
minDate,
|
|
81
|
+
maxDate,
|
|
82
|
+
disableFuture,
|
|
83
|
+
disablePast,
|
|
84
|
+
timezone
|
|
85
|
+
});
|
|
88
86
|
|
|
89
87
|
// Ensure that `calendarState.currentMonth` timezone is updated when `referenceDate` (or timezone changes)
|
|
90
88
|
// https://github.com/mui/mui-x/issues/10804
|
|
@@ -94,53 +92,65 @@ export const useCalendarState = params => {
|
|
|
94
92
|
newTimezone: utils.getTimezone(referenceDate)
|
|
95
93
|
});
|
|
96
94
|
}, [referenceDate, utils]);
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
onMonthChange(payload.newMonth);
|
|
103
|
-
}
|
|
104
|
-
}, [onMonthChange]);
|
|
105
|
-
const changeMonth = React.useCallback(newDate => {
|
|
106
|
-
const newDateRequested = newDate;
|
|
107
|
-
if (utils.isSameMonth(newDateRequested, calendarState.currentMonth)) {
|
|
95
|
+
const setVisibleDate = useEventCallback(({
|
|
96
|
+
target,
|
|
97
|
+
reason
|
|
98
|
+
}) => {
|
|
99
|
+
if (reason === 'cell-interaction' && calendarState.focusedDay != null && utils.isSameDay(target, calendarState.focusedDay)) {
|
|
108
100
|
return;
|
|
109
101
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
const skipAnimation = reason === 'cell-interaction';
|
|
103
|
+
let month;
|
|
104
|
+
let focusedDay;
|
|
105
|
+
if (reason === 'cell-interaction') {
|
|
106
|
+
month = getCurrentMonthFromVisibleDate(target, calendarState.currentMonth);
|
|
107
|
+
focusedDay = target;
|
|
108
|
+
} else {
|
|
109
|
+
month = utils.isSameMonth(target, calendarState.currentMonth) ? calendarState.currentMonth : utils.startOfMonth(target);
|
|
110
|
+
focusedDay = target;
|
|
111
|
+
|
|
112
|
+
// If the date is disabled, we try to find a non-disabled date inside the same month.
|
|
113
|
+
if (isDateDisabled(focusedDay)) {
|
|
114
|
+
const startOfMonth = utils.startOfMonth(target);
|
|
115
|
+
const endOfMonth = utils.endOfMonth(target);
|
|
116
|
+
focusedDay = findClosestEnabledDate({
|
|
117
|
+
utils,
|
|
118
|
+
date: focusedDay,
|
|
119
|
+
minDate: utils.isBefore(minDate, startOfMonth) ? startOfMonth : minDate,
|
|
120
|
+
maxDate: utils.isAfter(maxDate, endOfMonth) ? endOfMonth : maxDate,
|
|
121
|
+
disablePast,
|
|
122
|
+
disableFuture,
|
|
123
|
+
isDateDisabled,
|
|
124
|
+
timezone
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const hasChangedMonth = !utils.isSameMonth(calendarState.currentMonth, month);
|
|
129
|
+
const hasChangedYear = !utils.isSameYear(calendarState.currentMonth, month);
|
|
130
|
+
if (hasChangedMonth) {
|
|
131
|
+
onMonthChange?.(month);
|
|
132
|
+
}
|
|
133
|
+
if (hasChangedYear) {
|
|
134
|
+
onYearChange?.(utils.startOfYear(month));
|
|
135
|
+
}
|
|
136
|
+
dispatch({
|
|
137
|
+
type: 'setVisibleDate',
|
|
138
|
+
month,
|
|
139
|
+
direction: utils.isAfterDay(month, calendarState.currentMonth) ? 'left' : 'right',
|
|
140
|
+
focusedDay: calendarState.focusedDay != null && focusedDay != null && utils.isSameDay(focusedDay, calendarState.focusedDay) ? calendarState.focusedDay : focusedDay,
|
|
141
|
+
skipAnimation
|
|
113
142
|
});
|
|
114
|
-
}, [calendarState.currentMonth, handleChangeMonth, utils]);
|
|
115
|
-
const isDateDisabled = useIsDateDisabled({
|
|
116
|
-
shouldDisableDate,
|
|
117
|
-
minDate,
|
|
118
|
-
maxDate,
|
|
119
|
-
disableFuture,
|
|
120
|
-
disablePast,
|
|
121
|
-
timezone
|
|
122
143
|
});
|
|
123
144
|
const onMonthSwitchingAnimationEnd = React.useCallback(() => {
|
|
124
145
|
dispatch({
|
|
125
146
|
type: 'finishMonthSwitchingAnimation'
|
|
126
147
|
});
|
|
127
148
|
}, []);
|
|
128
|
-
const changeFocusedDay = useEventCallback((newFocusedDate, withoutMonthSwitchingAnimation) => {
|
|
129
|
-
if (!isDateDisabled(newFocusedDate)) {
|
|
130
|
-
dispatch({
|
|
131
|
-
type: 'changeFocusedDay',
|
|
132
|
-
focusedDay: newFocusedDate,
|
|
133
|
-
withoutMonthSwitchingAnimation
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
149
|
return {
|
|
138
150
|
referenceDate,
|
|
139
151
|
calendarState,
|
|
140
|
-
|
|
141
|
-
changeFocusedDay,
|
|
152
|
+
setVisibleDate,
|
|
142
153
|
isDateDisabled,
|
|
143
|
-
onMonthSwitchingAnimationEnd
|
|
144
|
-
handleChangeMonth
|
|
154
|
+
onMonthSwitchingAnimationEnd
|
|
145
155
|
};
|
|
146
156
|
};
|
|
@@ -159,8 +159,8 @@ const PickersCalendarHeader = /*#__PURE__*/React.forwardRef(function PickersCale
|
|
|
159
159
|
className: classes.switchViewIcon
|
|
160
160
|
}),
|
|
161
161
|
switchViewIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);
|
|
162
|
-
const selectNextMonth = () => onMonthChange(utils.addMonths(month, 1)
|
|
163
|
-
const selectPreviousMonth = () => onMonthChange(utils.addMonths(month, -1)
|
|
162
|
+
const selectNextMonth = () => onMonthChange(utils.addMonths(month, 1));
|
|
163
|
+
const selectPreviousMonth = () => onMonthChange(utils.addMonths(month, -1));
|
|
164
164
|
const isNextMonthDisabled = useNextMonthDisabled(month, {
|
|
165
165
|
disableFuture,
|
|
166
166
|
maxDate,
|
|
@@ -6,7 +6,6 @@ import { SxProps, Theme } from '@mui/material/styles';
|
|
|
6
6
|
import { ExportedPickersArrowSwitcherProps, PickersArrowSwitcherSlots, PickersArrowSwitcherSlotProps } from '../internals/components/PickersArrowSwitcher';
|
|
7
7
|
import { MonthValidationOptions } from '../internals/hooks/date-helpers-hooks';
|
|
8
8
|
import { PickerValidDate, DateView, PickerOwnerState } from '../models';
|
|
9
|
-
import { SlideDirection } from '../DateCalendar/PickersSlideTransition';
|
|
10
9
|
import { PickersCalendarHeaderClasses } from './pickersCalendarHeaderClasses';
|
|
11
10
|
export interface PickersCalendarHeaderSlots extends PickersArrowSwitcherSlots {
|
|
12
11
|
/**
|
|
@@ -40,7 +39,7 @@ export interface PickersCalendarHeaderProps extends ExportedPickersArrowSwitcher
|
|
|
40
39
|
currentMonth: PickerValidDate;
|
|
41
40
|
disabled?: boolean;
|
|
42
41
|
views: readonly DateView[];
|
|
43
|
-
onMonthChange: (date: PickerValidDate
|
|
42
|
+
onMonthChange: (date: PickerValidDate) => void;
|
|
44
43
|
view: DateView;
|
|
45
44
|
reduceAnimations: boolean;
|
|
46
45
|
onViewChange?: (view: DateView) => void;
|