@mui/x-date-pickers 7.20.0 → 7.22.0
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/AdapterDayjs/AdapterDayjs.js +2 -0
- package/CHANGELOG.md +200 -31
- package/DateCalendar/DayCalendar.js +3 -4
- package/DateCalendar/useCalendarState.d.ts +3 -1
- package/DateCalendar/useCalendarState.js +27 -2
- package/DigitalClock/DigitalClock.js +10 -12
- package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +2 -8
- package/PickersSectionList/PickersSectionList.d.ts +9 -0
- package/PickersSectionList/PickersSectionList.js +30 -9
- package/index.js +1 -1
- package/internals/hooks/useDesktopPicker/useDesktopPicker.js +3 -7
- package/internals/hooks/useDesktopPicker/useDesktopPicker.types.d.ts +2 -5
- package/internals/hooks/useField/useField.js +1 -1
- package/internals/hooks/usePicker/usePicker.js +8 -1
- package/internals/hooks/usePicker/usePicker.types.d.ts +2 -1
- package/internals/hooks/usePicker/usePickerOwnerState.d.ts +9 -0
- package/internals/hooks/usePicker/usePickerOwnerState.js +13 -0
- package/internals/utils/utils.js +2 -2
- package/models/pickers.d.ts +18 -0
- package/modern/AdapterDayjs/AdapterDayjs.js +2 -0
- package/modern/DateCalendar/DayCalendar.js +3 -4
- package/modern/DateCalendar/useCalendarState.js +27 -2
- package/modern/DigitalClock/DigitalClock.js +10 -12
- package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +2 -8
- package/modern/PickersSectionList/PickersSectionList.js +30 -9
- package/modern/index.js +1 -1
- package/modern/internals/hooks/useDesktopPicker/useDesktopPicker.js +3 -7
- package/modern/internals/hooks/useField/useField.js +1 -1
- package/modern/internals/hooks/usePicker/usePicker.js +8 -1
- package/modern/internals/hooks/usePicker/usePickerOwnerState.js +13 -0
- package/modern/internals/utils/utils.js +2 -2
- package/node/AdapterDayjs/AdapterDayjs.js +2 -0
- package/node/DateCalendar/DayCalendar.js +3 -4
- package/node/DateCalendar/useCalendarState.js +27 -2
- package/node/DigitalClock/DigitalClock.js +10 -12
- package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +2 -8
- package/node/PickersSectionList/PickersSectionList.js +30 -9
- package/node/index.js +1 -1
- package/node/internals/hooks/useDesktopPicker/useDesktopPicker.js +3 -7
- package/node/internals/hooks/useField/useField.js +1 -1
- package/node/internals/hooks/usePicker/usePicker.js +8 -1
- package/node/internals/hooks/usePicker/usePickerOwnerState.js +20 -0
- package/node/internals/utils/utils.js +2 -2
- package/package.json +2 -2
|
@@ -49,15 +49,6 @@ const useUtilityClasses = ownerState => {
|
|
|
49
49
|
};
|
|
50
50
|
return composeClasses(slots, getPickersSectionListUtilityClass, classes);
|
|
51
51
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Demos:
|
|
54
|
-
*
|
|
55
|
-
* - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
|
|
56
|
-
*
|
|
57
|
-
* API:
|
|
58
|
-
*
|
|
59
|
-
* - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
|
|
60
|
-
*/
|
|
61
52
|
function PickersSection(props) {
|
|
62
53
|
const {
|
|
63
54
|
slots,
|
|
@@ -105,6 +96,36 @@ function PickersSection(props) {
|
|
|
105
96
|
children: [/*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorBeforeProps)), /*#__PURE__*/_jsx(SectionContent, _extends({}, sectionContentProps)), /*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorAfterProps))]
|
|
106
97
|
}));
|
|
107
98
|
}
|
|
99
|
+
process.env.NODE_ENV !== "production" ? PickersSection.propTypes = {
|
|
100
|
+
// ----------------------------- Warning --------------------------------
|
|
101
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
102
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
103
|
+
// ----------------------------------------------------------------------
|
|
104
|
+
classes: PropTypes.object.isRequired,
|
|
105
|
+
element: PropTypes.shape({
|
|
106
|
+
after: PropTypes.object.isRequired,
|
|
107
|
+
before: PropTypes.object.isRequired,
|
|
108
|
+
container: PropTypes.object.isRequired,
|
|
109
|
+
content: PropTypes.object.isRequired
|
|
110
|
+
}).isRequired,
|
|
111
|
+
/**
|
|
112
|
+
* The props used for each component slot.
|
|
113
|
+
*/
|
|
114
|
+
slotProps: PropTypes.object,
|
|
115
|
+
/**
|
|
116
|
+
* Overridable component slots.
|
|
117
|
+
*/
|
|
118
|
+
slots: PropTypes.object
|
|
119
|
+
} : void 0;
|
|
120
|
+
/**
|
|
121
|
+
* Demos:
|
|
122
|
+
*
|
|
123
|
+
* - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
|
|
124
|
+
*
|
|
125
|
+
* API:
|
|
126
|
+
*
|
|
127
|
+
* - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
|
|
128
|
+
*/
|
|
108
129
|
const PickersSectionList = /*#__PURE__*/React.forwardRef(function PickersSectionList(inProps, ref) {
|
|
109
130
|
const props = useThemeProps({
|
|
110
131
|
props: inProps,
|
package/index.js
CHANGED
|
@@ -59,7 +59,8 @@ export const useDesktopPicker = _ref => {
|
|
|
59
59
|
renderCurrentView,
|
|
60
60
|
shouldRestoreFocus,
|
|
61
61
|
fieldProps: pickerFieldProps,
|
|
62
|
-
contextValue
|
|
62
|
+
contextValue,
|
|
63
|
+
ownerState
|
|
63
64
|
} = usePicker(_extends({}, pickerParams, {
|
|
64
65
|
props,
|
|
65
66
|
fieldRef,
|
|
@@ -67,11 +68,6 @@ export const useDesktopPicker = _ref => {
|
|
|
67
68
|
additionalViewProps: {},
|
|
68
69
|
wrapperVariant: 'desktop'
|
|
69
70
|
}));
|
|
70
|
-
|
|
71
|
-
// TODO v8: Apply this ownerState to all the slots in this hook.
|
|
72
|
-
const ownerStateV8 = {
|
|
73
|
-
open
|
|
74
|
-
};
|
|
75
71
|
const InputAdornment = slots.inputAdornment ?? MuiInputAdornment;
|
|
76
72
|
const _useSlotProps = useSlotProps({
|
|
77
73
|
elementType: InputAdornment,
|
|
@@ -99,7 +95,7 @@ export const useDesktopPicker = _ref => {
|
|
|
99
95
|
const openPickerIconProps = useSlotProps({
|
|
100
96
|
elementType: OpenPickerIcon,
|
|
101
97
|
externalSlotProps: innerSlotProps?.openPickerIcon,
|
|
102
|
-
ownerState
|
|
98
|
+
ownerState
|
|
103
99
|
});
|
|
104
100
|
const Field = slots.field;
|
|
105
101
|
const fieldProps = useSlotProps({
|
|
@@ -6,7 +6,7 @@ import { SlotComponentProps } from '@mui/utils';
|
|
|
6
6
|
import { BaseNonStaticPickerProps, BasePickerProps, BaseNonRangeNonStaticPickerProps } from '../../models/props/basePickerProps';
|
|
7
7
|
import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper';
|
|
8
8
|
import { UsePickerParams, UsePickerProps } from '../usePicker';
|
|
9
|
-
import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models';
|
|
9
|
+
import { BaseSingleInputFieldProps, FieldSection, PickerOwnerState, PickerValidDate } from '../../../models';
|
|
10
10
|
import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, PickersLayoutSlotProps } from '../../../PickersLayout/PickersLayout.types';
|
|
11
11
|
import { UsePickerValueNonStaticProps } from '../usePicker/usePickerValue.types';
|
|
12
12
|
import { UsePickerViewsNonStaticProps, UsePickerViewsProps } from '../usePicker/usePickerViews';
|
|
@@ -40,15 +40,12 @@ export interface UseDesktopPickerSlots<TDate extends PickerValidDate, TView exte
|
|
|
40
40
|
}
|
|
41
41
|
export interface UseDesktopPickerSlotProps<TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean> extends ExportedUseDesktopPickerSlotProps<TDate, TView, TEnableAccessibleFieldDOMStructure>, Pick<PickersLayoutSlotProps<TDate | null, TDate, TView>, 'toolbar'> {
|
|
42
42
|
}
|
|
43
|
-
export interface UseDesktopPickerOwnerState {
|
|
44
|
-
open: boolean;
|
|
45
|
-
}
|
|
46
43
|
export interface ExportedUseDesktopPickerSlotProps<TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean> extends PickersPopperSlotProps, ExportedPickersLayoutSlotProps<TDate | null, TDate, TView>, UseClearableFieldSlotProps {
|
|
47
44
|
field?: SlotComponentPropsFromProps<BaseSingleInputFieldProps<TDate | null, TDate, FieldSection, TEnableAccessibleFieldDOMStructure, unknown>, {}, UsePickerProps<TDate | null, TDate, any, any, any, any>>;
|
|
48
45
|
textField?: SlotComponentProps<typeof TextField, {}, Record<string, any>>;
|
|
49
46
|
inputAdornment?: Partial<InputAdornmentProps>;
|
|
50
47
|
openPickerButton?: SlotComponentProps<typeof IconButton, {}, UseDesktopPickerProps<TDate, any, TEnableAccessibleFieldDOMStructure, any, any>>;
|
|
51
|
-
openPickerIcon?: SlotComponentPropsFromProps<Record<string, any>, {},
|
|
48
|
+
openPickerIcon?: SlotComponentPropsFromProps<Record<string, any>, {}, PickerOwnerState<TDate | null>>;
|
|
52
49
|
}
|
|
53
50
|
export interface DesktopOnlyPickerProps extends BaseNonStaticPickerProps, BaseNonRangeNonStaticPickerProps, UsePickerValueNonStaticProps, UsePickerViewsNonStaticProps {
|
|
54
51
|
/**
|
|
@@ -75,7 +75,7 @@ export const useField = params => {
|
|
|
75
75
|
// eslint-disable-next-line default-case
|
|
76
76
|
switch (true) {
|
|
77
77
|
// Select all
|
|
78
|
-
case (event.ctrlKey || event.metaKey) && event.
|
|
78
|
+
case (event.ctrlKey || event.metaKey) && String.fromCharCode(event.keyCode) === 'A' && !event.shiftKey && !event.altKey:
|
|
79
79
|
{
|
|
80
80
|
// prevent default to make sure that the next line "select all" while updating
|
|
81
81
|
// the internal state at the same time.
|
|
@@ -2,6 +2,7 @@ import { warnOnce } from '@mui/x-internals/warning';
|
|
|
2
2
|
import { usePickerValue } from "./usePickerValue.js";
|
|
3
3
|
import { usePickerViews } from "./usePickerViews.js";
|
|
4
4
|
import { usePickerLayoutProps } from "./usePickerLayoutProps.js";
|
|
5
|
+
import { usePickerOwnerState } from "./usePickerOwnerState.js";
|
|
5
6
|
export const usePicker = ({
|
|
6
7
|
props,
|
|
7
8
|
valueManager,
|
|
@@ -39,6 +40,10 @@ export const usePicker = ({
|
|
|
39
40
|
propsFromPickerValue: pickerValueResponse.layoutProps,
|
|
40
41
|
propsFromPickerViews: pickerViewsResponse.layoutProps
|
|
41
42
|
});
|
|
43
|
+
const pickerOwnerState = usePickerOwnerState({
|
|
44
|
+
props,
|
|
45
|
+
pickerValueResponse
|
|
46
|
+
});
|
|
42
47
|
return {
|
|
43
48
|
// Picker value
|
|
44
49
|
open: pickerValueResponse.open,
|
|
@@ -51,6 +56,8 @@ export const usePicker = ({
|
|
|
51
56
|
// Picker layout
|
|
52
57
|
layoutProps: pickerLayoutResponse.layoutProps,
|
|
53
58
|
// Picker context
|
|
54
|
-
contextValue: pickerValueResponse.contextValue
|
|
59
|
+
contextValue: pickerValueResponse.contextValue,
|
|
60
|
+
// Picker owner state
|
|
61
|
+
ownerState: pickerOwnerState
|
|
55
62
|
};
|
|
56
63
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UsePickerValueParams, UsePickerValueProps, UsePickerValueBaseProps, UsePickerValueResponse } from './usePickerValue.types';
|
|
2
2
|
import { UsePickerViewsProps, UsePickerViewParams, UsePickerViewsResponse, UsePickerViewsBaseProps } from './usePickerViews';
|
|
3
3
|
import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps';
|
|
4
|
-
import { FieldSection, PickerValidDate } from '../../../models';
|
|
4
|
+
import { FieldSection, PickerOwnerState, PickerValidDate } from '../../../models';
|
|
5
5
|
import { DateOrTimeViewWithMeridiem } from '../../models';
|
|
6
6
|
/**
|
|
7
7
|
* Props common to all picker headless implementations.
|
|
@@ -14,4 +14,5 @@ export interface UsePickerParams<TValue, TDate extends PickerValidDate, TView ex
|
|
|
14
14
|
props: TExternalProps;
|
|
15
15
|
}
|
|
16
16
|
export interface UsePickerResponse<TValue, TView extends DateOrTimeViewWithMeridiem, TSection extends FieldSection, TError> extends Omit<UsePickerValueResponse<TValue, TSection, TError>, 'viewProps' | 'layoutProps'>, Omit<UsePickerViewsResponse<TView>, 'layoutProps'>, UsePickerLayoutPropsResponse<TValue, TView> {
|
|
17
|
+
ownerState: PickerOwnerState<TValue>;
|
|
17
18
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FieldSection, PickerOwnerState } from '../../../models';
|
|
2
|
+
import type { UsePickerProps } from './usePicker.types';
|
|
3
|
+
import { UsePickerValueResponse } from './usePickerValue.types';
|
|
4
|
+
interface UsePickerOwnerStateParameters<TValue> {
|
|
5
|
+
props: UsePickerProps<TValue, any, any, any, any, any>;
|
|
6
|
+
pickerValueResponse: UsePickerValueResponse<TValue, FieldSection, any>;
|
|
7
|
+
}
|
|
8
|
+
export declare function usePickerOwnerState<TValue>(parameters: UsePickerOwnerStateParameters<TValue>): PickerOwnerState<TValue>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export function usePickerOwnerState(parameters) {
|
|
3
|
+
const {
|
|
4
|
+
props,
|
|
5
|
+
pickerValueResponse
|
|
6
|
+
} = parameters;
|
|
7
|
+
return React.useMemo(() => ({
|
|
8
|
+
value: pickerValueResponse.viewProps.value,
|
|
9
|
+
open: pickerValueResponse.open,
|
|
10
|
+
disabled: props.disabled ?? false,
|
|
11
|
+
readOnly: props.readOnly ?? false
|
|
12
|
+
}), [pickerValueResponse.viewProps.value, pickerValueResponse.open, props.disabled, props.readOnly]);
|
|
13
|
+
}
|
package/internals/utils/utils.js
CHANGED
|
@@ -40,7 +40,7 @@ export const getActiveElement = (root = document) => {
|
|
|
40
40
|
* @returns {number} The index of the focused list item, or -1 if none is focused.
|
|
41
41
|
*/
|
|
42
42
|
export const getFocusedListItemIndex = listElement => {
|
|
43
|
-
const children = listElement.children;
|
|
44
|
-
return
|
|
43
|
+
const children = Array.from(listElement.children);
|
|
44
|
+
return children.indexOf(getActiveElement(document));
|
|
45
45
|
};
|
|
46
46
|
export const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
|
package/models/pickers.d.ts
CHANGED
|
@@ -10,3 +10,21 @@ export interface PickerChangeHandlerContext<TError> {
|
|
|
10
10
|
export interface PickerValidDateLookup {
|
|
11
11
|
}
|
|
12
12
|
export type PickerValidDate = keyof PickerValidDateLookup extends never ? any : PickerValidDateLookup[keyof PickerValidDateLookup];
|
|
13
|
+
export interface PickerOwnerState<TValue> {
|
|
14
|
+
/**
|
|
15
|
+
* The value currently displayed in the field and in the view.
|
|
16
|
+
*/
|
|
17
|
+
value: TValue;
|
|
18
|
+
/**
|
|
19
|
+
* `true` if the picker is open, `false` otherwise.
|
|
20
|
+
*/
|
|
21
|
+
open: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* `true` if the picker is disabled, `false` otherwise.
|
|
24
|
+
*/
|
|
25
|
+
disabled: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* `true` if the picker is read-only, `false` otherwise.
|
|
28
|
+
*/
|
|
29
|
+
readOnly: boolean;
|
|
30
|
+
}
|
|
@@ -254,6 +254,8 @@ export class AdapterDayjs {
|
|
|
254
254
|
const timezone = this.getTimezone(value);
|
|
255
255
|
if (timezone !== 'UTC') {
|
|
256
256
|
const fixedValue = value.tz(this.cleanTimezone(timezone), true);
|
|
257
|
+
// TODO: Simplify the case when we raise the `dayjs` peer dep to 1.11.12 (https://github.com/iamkun/dayjs/releases/tag/v1.11.12)
|
|
258
|
+
/* istanbul ignore next */
|
|
257
259
|
// @ts-ignore
|
|
258
260
|
if (fixedValue.$offset === (value.$offset ?? 0)) {
|
|
259
261
|
return value;
|
|
@@ -378,9 +378,8 @@ export function DayCalendar(inProps) {
|
|
|
378
378
|
return internalFocusedDay;
|
|
379
379
|
}, [currentMonth, disableFuture, disablePast, internalFocusedDay, isDateDisabled, utils, timezone]);
|
|
380
380
|
const weeksToDisplay = React.useMemo(() => {
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
let nextMonth = utils.addMonths(currentMonthWithTimezone, 1);
|
|
381
|
+
const toDisplay = utils.getWeekArray(currentMonth);
|
|
382
|
+
let nextMonth = utils.addMonths(currentMonth, 1);
|
|
384
383
|
while (fixedWeekNumber && toDisplay.length < fixedWeekNumber) {
|
|
385
384
|
const additionalWeeks = utils.getWeekArray(nextMonth);
|
|
386
385
|
const hasCommonWeek = utils.isSameDay(toDisplay[toDisplay.length - 1][0], additionalWeeks[0][0]);
|
|
@@ -392,7 +391,7 @@ export function DayCalendar(inProps) {
|
|
|
392
391
|
nextMonth = utils.addMonths(nextMonth, 1);
|
|
393
392
|
}
|
|
394
393
|
return toDisplay;
|
|
395
|
-
}, [currentMonth, fixedWeekNumber, utils
|
|
394
|
+
}, [currentMonth, fixedWeekNumber, utils]);
|
|
396
395
|
return /*#__PURE__*/_jsxs(PickersCalendarDayRoot, {
|
|
397
396
|
role: "grid",
|
|
398
397
|
"aria-labelledby": gridLabelId,
|
|
@@ -15,6 +15,20 @@ export const createCalendarStateReducer = (reduceAnimations, disableSwitchToMont
|
|
|
15
15
|
currentMonth: action.newMonth,
|
|
16
16
|
isMonthSwitchingAnimating: !reduceAnimations
|
|
17
17
|
});
|
|
18
|
+
case 'changeMonthTimezone':
|
|
19
|
+
{
|
|
20
|
+
const newTimezone = action.newTimezone;
|
|
21
|
+
if (utils.getTimezone(state.currentMonth) === newTimezone) {
|
|
22
|
+
return state;
|
|
23
|
+
}
|
|
24
|
+
let newCurrentMonth = utils.setTimezone(state.currentMonth, newTimezone);
|
|
25
|
+
if (utils.getMonth(newCurrentMonth) !== utils.getMonth(state.currentMonth)) {
|
|
26
|
+
newCurrentMonth = utils.setMonth(newCurrentMonth, utils.getMonth(state.currentMonth));
|
|
27
|
+
}
|
|
28
|
+
return _extends({}, state, {
|
|
29
|
+
currentMonth: newCurrentMonth
|
|
30
|
+
});
|
|
31
|
+
}
|
|
18
32
|
case 'finishMonthSwitchingAnimation':
|
|
19
33
|
return _extends({}, state, {
|
|
20
34
|
isMonthSwitchingAnimating: false
|
|
@@ -61,14 +75,25 @@ export const useCalendarState = params => {
|
|
|
61
75
|
referenceDate: referenceDateProp,
|
|
62
76
|
granularity: SECTION_TYPE_GRANULARITY.day
|
|
63
77
|
});
|
|
64
|
-
},
|
|
65
|
-
)
|
|
78
|
+
},
|
|
79
|
+
// We want the `referenceDate` to update on prop and `timezone` change (https://github.com/mui/mui-x/issues/10804)
|
|
80
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
|
+
[referenceDateProp, timezone]);
|
|
66
82
|
const [calendarState, dispatch] = React.useReducer(reducerFn, {
|
|
67
83
|
isMonthSwitchingAnimating: false,
|
|
68
84
|
focusedDay: referenceDate,
|
|
69
85
|
currentMonth: utils.startOfMonth(referenceDate),
|
|
70
86
|
slideDirection: 'left'
|
|
71
87
|
});
|
|
88
|
+
|
|
89
|
+
// Ensure that `calendarState.currentMonth` timezone is updated when `referenceDate` (or timezone changes)
|
|
90
|
+
// https://github.com/mui/mui-x/issues/10804
|
|
91
|
+
React.useEffect(() => {
|
|
92
|
+
dispatch({
|
|
93
|
+
type: 'changeMonthTimezone',
|
|
94
|
+
newTimezone: utils.getTimezone(referenceDate)
|
|
95
|
+
});
|
|
96
|
+
}, [referenceDate, utils]);
|
|
72
97
|
const handleChangeMonth = React.useCallback(payload => {
|
|
73
98
|
dispatch(_extends({
|
|
74
99
|
type: 'changeMonth'
|
|
@@ -232,21 +232,22 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
|
|
|
232
232
|
return !containsValidTime() || !isValidValue();
|
|
233
233
|
}, [disableIgnoringDatePartForTimeValidation, utils, minTime, maxTime, disableFuture, now, disablePast, minutesStep, shouldDisableTime]);
|
|
234
234
|
const timeOptions = React.useMemo(() => {
|
|
235
|
+
const result = [];
|
|
235
236
|
const startOfDay = utils.startOfDay(valueOrReferenceDate);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
let nextTimeStepOption = startOfDay;
|
|
238
|
+
while (utils.isSameDay(valueOrReferenceDate, nextTimeStepOption)) {
|
|
239
|
+
result.push(nextTimeStepOption);
|
|
240
|
+
nextTimeStepOption = utils.addMinutes(nextTimeStepOption, timeStep);
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
239
243
|
}, [valueOrReferenceDate, timeStep, utils]);
|
|
240
244
|
const focusedOptionIndex = timeOptions.findIndex(option => utils.isEqual(option, valueOrReferenceDate));
|
|
241
245
|
const handleKeyDown = event => {
|
|
242
246
|
switch (event.key) {
|
|
243
247
|
case 'PageUp':
|
|
244
248
|
{
|
|
245
|
-
if (!listRef.current) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
249
|
const newIndex = getFocusedListItemIndex(listRef.current) - 5;
|
|
249
|
-
const children = listRef.current
|
|
250
|
+
const children = listRef.current.children;
|
|
250
251
|
const newFocusedIndex = Math.max(0, newIndex);
|
|
251
252
|
const childToFocus = children[newFocusedIndex];
|
|
252
253
|
if (childToFocus) {
|
|
@@ -257,11 +258,8 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
|
|
|
257
258
|
}
|
|
258
259
|
case 'PageDown':
|
|
259
260
|
{
|
|
260
|
-
if (!listRef.current) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
261
|
const newIndex = getFocusedListItemIndex(listRef.current) + 5;
|
|
264
|
-
const children = listRef.current
|
|
262
|
+
const children = listRef.current.children;
|
|
265
263
|
const newFocusedIndex = Math.min(children.length - 1, newIndex);
|
|
266
264
|
const childToFocus = children[newFocusedIndex];
|
|
267
265
|
if (childToFocus) {
|
|
@@ -304,7 +302,7 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
|
|
|
304
302
|
tabIndex: tabIndex
|
|
305
303
|
}, clockItemProps, {
|
|
306
304
|
children: formattedValue
|
|
307
|
-
}), formattedValue);
|
|
305
|
+
}), `${option.valueOf()}-${formattedValue}`);
|
|
308
306
|
})
|
|
309
307
|
})
|
|
310
308
|
}));
|
|
@@ -143,11 +143,8 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
|
|
|
143
143
|
switch (event.key) {
|
|
144
144
|
case 'PageUp':
|
|
145
145
|
{
|
|
146
|
-
if (!containerRef.current) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
146
|
const newIndex = getFocusedListItemIndex(containerRef.current) - 5;
|
|
150
|
-
const children = containerRef.current
|
|
147
|
+
const children = containerRef.current.children;
|
|
151
148
|
const newFocusedIndex = Math.max(0, newIndex);
|
|
152
149
|
const childToFocus = children[newFocusedIndex];
|
|
153
150
|
if (childToFocus) {
|
|
@@ -158,11 +155,8 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
|
|
|
158
155
|
}
|
|
159
156
|
case 'PageDown':
|
|
160
157
|
{
|
|
161
|
-
if (!containerRef.current) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
158
|
const newIndex = getFocusedListItemIndex(containerRef.current) + 5;
|
|
165
|
-
const children = containerRef.current
|
|
159
|
+
const children = containerRef.current.children;
|
|
166
160
|
const newFocusedIndex = Math.min(children.length - 1, newIndex);
|
|
167
161
|
const childToFocus = children[newFocusedIndex];
|
|
168
162
|
if (childToFocus) {
|
|
@@ -49,15 +49,6 @@ const useUtilityClasses = ownerState => {
|
|
|
49
49
|
};
|
|
50
50
|
return composeClasses(slots, getPickersSectionListUtilityClass, classes);
|
|
51
51
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Demos:
|
|
54
|
-
*
|
|
55
|
-
* - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
|
|
56
|
-
*
|
|
57
|
-
* API:
|
|
58
|
-
*
|
|
59
|
-
* - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
|
|
60
|
-
*/
|
|
61
52
|
function PickersSection(props) {
|
|
62
53
|
const {
|
|
63
54
|
slots,
|
|
@@ -105,6 +96,36 @@ function PickersSection(props) {
|
|
|
105
96
|
children: [/*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorBeforeProps)), /*#__PURE__*/_jsx(SectionContent, _extends({}, sectionContentProps)), /*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorAfterProps))]
|
|
106
97
|
}));
|
|
107
98
|
}
|
|
99
|
+
process.env.NODE_ENV !== "production" ? PickersSection.propTypes = {
|
|
100
|
+
// ----------------------------- Warning --------------------------------
|
|
101
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
102
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
103
|
+
// ----------------------------------------------------------------------
|
|
104
|
+
classes: PropTypes.object.isRequired,
|
|
105
|
+
element: PropTypes.shape({
|
|
106
|
+
after: PropTypes.object.isRequired,
|
|
107
|
+
before: PropTypes.object.isRequired,
|
|
108
|
+
container: PropTypes.object.isRequired,
|
|
109
|
+
content: PropTypes.object.isRequired
|
|
110
|
+
}).isRequired,
|
|
111
|
+
/**
|
|
112
|
+
* The props used for each component slot.
|
|
113
|
+
*/
|
|
114
|
+
slotProps: PropTypes.object,
|
|
115
|
+
/**
|
|
116
|
+
* Overridable component slots.
|
|
117
|
+
*/
|
|
118
|
+
slots: PropTypes.object
|
|
119
|
+
} : void 0;
|
|
120
|
+
/**
|
|
121
|
+
* Demos:
|
|
122
|
+
*
|
|
123
|
+
* - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
|
|
124
|
+
*
|
|
125
|
+
* API:
|
|
126
|
+
*
|
|
127
|
+
* - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
|
|
128
|
+
*/
|
|
108
129
|
const PickersSectionList = /*#__PURE__*/React.forwardRef(function PickersSectionList(inProps, ref) {
|
|
109
130
|
const props = useThemeProps({
|
|
110
131
|
props: inProps,
|
package/modern/index.js
CHANGED
|
@@ -59,7 +59,8 @@ export const useDesktopPicker = _ref => {
|
|
|
59
59
|
renderCurrentView,
|
|
60
60
|
shouldRestoreFocus,
|
|
61
61
|
fieldProps: pickerFieldProps,
|
|
62
|
-
contextValue
|
|
62
|
+
contextValue,
|
|
63
|
+
ownerState
|
|
63
64
|
} = usePicker(_extends({}, pickerParams, {
|
|
64
65
|
props,
|
|
65
66
|
fieldRef,
|
|
@@ -67,11 +68,6 @@ export const useDesktopPicker = _ref => {
|
|
|
67
68
|
additionalViewProps: {},
|
|
68
69
|
wrapperVariant: 'desktop'
|
|
69
70
|
}));
|
|
70
|
-
|
|
71
|
-
// TODO v8: Apply this ownerState to all the slots in this hook.
|
|
72
|
-
const ownerStateV8 = {
|
|
73
|
-
open
|
|
74
|
-
};
|
|
75
71
|
const InputAdornment = slots.inputAdornment ?? MuiInputAdornment;
|
|
76
72
|
const _useSlotProps = useSlotProps({
|
|
77
73
|
elementType: InputAdornment,
|
|
@@ -99,7 +95,7 @@ export const useDesktopPicker = _ref => {
|
|
|
99
95
|
const openPickerIconProps = useSlotProps({
|
|
100
96
|
elementType: OpenPickerIcon,
|
|
101
97
|
externalSlotProps: innerSlotProps?.openPickerIcon,
|
|
102
|
-
ownerState
|
|
98
|
+
ownerState
|
|
103
99
|
});
|
|
104
100
|
const Field = slots.field;
|
|
105
101
|
const fieldProps = useSlotProps({
|
|
@@ -75,7 +75,7 @@ export const useField = params => {
|
|
|
75
75
|
// eslint-disable-next-line default-case
|
|
76
76
|
switch (true) {
|
|
77
77
|
// Select all
|
|
78
|
-
case (event.ctrlKey || event.metaKey) && event.
|
|
78
|
+
case (event.ctrlKey || event.metaKey) && String.fromCharCode(event.keyCode) === 'A' && !event.shiftKey && !event.altKey:
|
|
79
79
|
{
|
|
80
80
|
// prevent default to make sure that the next line "select all" while updating
|
|
81
81
|
// the internal state at the same time.
|
|
@@ -2,6 +2,7 @@ import { warnOnce } from '@mui/x-internals/warning';
|
|
|
2
2
|
import { usePickerValue } from "./usePickerValue.js";
|
|
3
3
|
import { usePickerViews } from "./usePickerViews.js";
|
|
4
4
|
import { usePickerLayoutProps } from "./usePickerLayoutProps.js";
|
|
5
|
+
import { usePickerOwnerState } from "./usePickerOwnerState.js";
|
|
5
6
|
export const usePicker = ({
|
|
6
7
|
props,
|
|
7
8
|
valueManager,
|
|
@@ -39,6 +40,10 @@ export const usePicker = ({
|
|
|
39
40
|
propsFromPickerValue: pickerValueResponse.layoutProps,
|
|
40
41
|
propsFromPickerViews: pickerViewsResponse.layoutProps
|
|
41
42
|
});
|
|
43
|
+
const pickerOwnerState = usePickerOwnerState({
|
|
44
|
+
props,
|
|
45
|
+
pickerValueResponse
|
|
46
|
+
});
|
|
42
47
|
return {
|
|
43
48
|
// Picker value
|
|
44
49
|
open: pickerValueResponse.open,
|
|
@@ -51,6 +56,8 @@ export const usePicker = ({
|
|
|
51
56
|
// Picker layout
|
|
52
57
|
layoutProps: pickerLayoutResponse.layoutProps,
|
|
53
58
|
// Picker context
|
|
54
|
-
contextValue: pickerValueResponse.contextValue
|
|
59
|
+
contextValue: pickerValueResponse.contextValue,
|
|
60
|
+
// Picker owner state
|
|
61
|
+
ownerState: pickerOwnerState
|
|
55
62
|
};
|
|
56
63
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export function usePickerOwnerState(parameters) {
|
|
3
|
+
const {
|
|
4
|
+
props,
|
|
5
|
+
pickerValueResponse
|
|
6
|
+
} = parameters;
|
|
7
|
+
return React.useMemo(() => ({
|
|
8
|
+
value: pickerValueResponse.viewProps.value,
|
|
9
|
+
open: pickerValueResponse.open,
|
|
10
|
+
disabled: props.disabled ?? false,
|
|
11
|
+
readOnly: props.readOnly ?? false
|
|
12
|
+
}), [pickerValueResponse.viewProps.value, pickerValueResponse.open, props.disabled, props.readOnly]);
|
|
13
|
+
}
|
|
@@ -40,7 +40,7 @@ export const getActiveElement = (root = document) => {
|
|
|
40
40
|
* @returns {number} The index of the focused list item, or -1 if none is focused.
|
|
41
41
|
*/
|
|
42
42
|
export const getFocusedListItemIndex = listElement => {
|
|
43
|
-
const children = listElement.children;
|
|
44
|
-
return
|
|
43
|
+
const children = Array.from(listElement.children);
|
|
44
|
+
return children.indexOf(getActiveElement(document));
|
|
45
45
|
};
|
|
46
46
|
export const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';
|
|
@@ -262,6 +262,8 @@ class AdapterDayjs {
|
|
|
262
262
|
const timezone = this.getTimezone(value);
|
|
263
263
|
if (timezone !== 'UTC') {
|
|
264
264
|
const fixedValue = value.tz(this.cleanTimezone(timezone), true);
|
|
265
|
+
// TODO: Simplify the case when we raise the `dayjs` peer dep to 1.11.12 (https://github.com/iamkun/dayjs/releases/tag/v1.11.12)
|
|
266
|
+
/* istanbul ignore next */
|
|
265
267
|
// @ts-ignore
|
|
266
268
|
if (fixedValue.$offset === (value.$offset ?? 0)) {
|
|
267
269
|
return value;
|
|
@@ -386,9 +386,8 @@ function DayCalendar(inProps) {
|
|
|
386
386
|
return internalFocusedDay;
|
|
387
387
|
}, [currentMonth, disableFuture, disablePast, internalFocusedDay, isDateDisabled, utils, timezone]);
|
|
388
388
|
const weeksToDisplay = React.useMemo(() => {
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
let nextMonth = utils.addMonths(currentMonthWithTimezone, 1);
|
|
389
|
+
const toDisplay = utils.getWeekArray(currentMonth);
|
|
390
|
+
let nextMonth = utils.addMonths(currentMonth, 1);
|
|
392
391
|
while (fixedWeekNumber && toDisplay.length < fixedWeekNumber) {
|
|
393
392
|
const additionalWeeks = utils.getWeekArray(nextMonth);
|
|
394
393
|
const hasCommonWeek = utils.isSameDay(toDisplay[toDisplay.length - 1][0], additionalWeeks[0][0]);
|
|
@@ -400,7 +399,7 @@ function DayCalendar(inProps) {
|
|
|
400
399
|
nextMonth = utils.addMonths(nextMonth, 1);
|
|
401
400
|
}
|
|
402
401
|
return toDisplay;
|
|
403
|
-
}, [currentMonth, fixedWeekNumber, utils
|
|
402
|
+
}, [currentMonth, fixedWeekNumber, utils]);
|
|
404
403
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(PickersCalendarDayRoot, {
|
|
405
404
|
role: "grid",
|
|
406
405
|
"aria-labelledby": gridLabelId,
|
|
@@ -22,6 +22,20 @@ const createCalendarStateReducer = (reduceAnimations, disableSwitchToMonthOnDayF
|
|
|
22
22
|
currentMonth: action.newMonth,
|
|
23
23
|
isMonthSwitchingAnimating: !reduceAnimations
|
|
24
24
|
});
|
|
25
|
+
case 'changeMonthTimezone':
|
|
26
|
+
{
|
|
27
|
+
const newTimezone = action.newTimezone;
|
|
28
|
+
if (utils.getTimezone(state.currentMonth) === newTimezone) {
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
let newCurrentMonth = utils.setTimezone(state.currentMonth, newTimezone);
|
|
32
|
+
if (utils.getMonth(newCurrentMonth) !== utils.getMonth(state.currentMonth)) {
|
|
33
|
+
newCurrentMonth = utils.setMonth(newCurrentMonth, utils.getMonth(state.currentMonth));
|
|
34
|
+
}
|
|
35
|
+
return (0, _extends2.default)({}, state, {
|
|
36
|
+
currentMonth: newCurrentMonth
|
|
37
|
+
});
|
|
38
|
+
}
|
|
25
39
|
case 'finishMonthSwitchingAnimation':
|
|
26
40
|
return (0, _extends2.default)({}, state, {
|
|
27
41
|
isMonthSwitchingAnimating: false
|
|
@@ -69,14 +83,25 @@ const useCalendarState = params => {
|
|
|
69
83
|
referenceDate: referenceDateProp,
|
|
70
84
|
granularity: _getDefaultReferenceDate.SECTION_TYPE_GRANULARITY.day
|
|
71
85
|
});
|
|
72
|
-
},
|
|
73
|
-
)
|
|
86
|
+
},
|
|
87
|
+
// We want the `referenceDate` to update on prop and `timezone` change (https://github.com/mui/mui-x/issues/10804)
|
|
88
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
89
|
+
[referenceDateProp, timezone]);
|
|
74
90
|
const [calendarState, dispatch] = React.useReducer(reducerFn, {
|
|
75
91
|
isMonthSwitchingAnimating: false,
|
|
76
92
|
focusedDay: referenceDate,
|
|
77
93
|
currentMonth: utils.startOfMonth(referenceDate),
|
|
78
94
|
slideDirection: 'left'
|
|
79
95
|
});
|
|
96
|
+
|
|
97
|
+
// Ensure that `calendarState.currentMonth` timezone is updated when `referenceDate` (or timezone changes)
|
|
98
|
+
// https://github.com/mui/mui-x/issues/10804
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
dispatch({
|
|
101
|
+
type: 'changeMonthTimezone',
|
|
102
|
+
newTimezone: utils.getTimezone(referenceDate)
|
|
103
|
+
});
|
|
104
|
+
}, [referenceDate, utils]);
|
|
80
105
|
const handleChangeMonth = React.useCallback(payload => {
|
|
81
106
|
dispatch((0, _extends2.default)({
|
|
82
107
|
type: 'changeMonth'
|