@mui/x-date-pickers 6.0.3 → 6.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AdapterDateFnsJalali/index.js +68 -0
- package/AdapterLuxon/index.js +12 -3
- package/CHANGELOG.md +61 -0
- package/DateCalendar/DateCalendar.types.d.ts +1 -1
- package/DateCalendar/PickersCalendarHeader.d.ts +1 -1
- package/DateCalendar/index.d.ts +0 -1
- package/DateField/DateField.types.d.ts +2 -2
- package/DatePicker/DatePickerToolbar.d.ts +1 -1
- package/DatePicker/shared.d.ts +2 -2
- package/DateTimeField/DateTimeField.types.d.ts +2 -2
- package/DateTimePicker/DateTimePickerTabs.d.ts +1 -1
- package/DateTimePicker/DateTimePickerToolbar.d.ts +1 -1
- package/DateTimePicker/shared.d.ts +1 -2
- package/DesktopDatePicker/DesktopDatePicker.types.d.ts +1 -1
- package/DesktopDateTimePicker/DesktopDateTimePicker.types.d.ts +1 -1
- package/DesktopTimePicker/DesktopTimePicker.types.d.ts +1 -1
- package/MobileDatePicker/MobileDatePicker.types.d.ts +1 -1
- package/MobileDateTimePicker/MobileDateTimePicker.types.d.ts +1 -1
- package/MobileTimePicker/MobileTimePicker.types.d.ts +1 -1
- package/PickersLayout/PickersLayout.d.ts +1 -1
- package/PickersLayout/PickersLayout.types.d.ts +1 -1
- package/PickersLayout/index.d.ts +1 -1
- package/PickersLayout/usePickerLayout.d.ts +1 -1
- package/README.md +1 -1
- package/StaticDatePicker/StaticDatePicker.types.d.ts +2 -1
- package/StaticDateTimePicker/StaticDateTimePicker.types.d.ts +2 -1
- package/StaticTimePicker/StaticTimePicker.types.d.ts +2 -1
- package/TimeClock/Clock.d.ts +1 -1
- package/TimeClock/ClockPointer.d.ts +1 -1
- package/TimeClock/TimeClock.types.d.ts +1 -1
- package/TimeClock/index.d.ts +0 -1
- package/TimeField/TimeField.types.d.ts +2 -2
- package/TimePicker/TimePickerToolbar.d.ts +1 -1
- package/TimePicker/shared.d.ts +1 -2
- package/dateViewRenderers/dateViewRenderers.d.ts +1 -1
- package/index.js +1 -1
- package/internals/components/PickersToolbar.d.ts +1 -1
- package/internals/demo/DemoContainer.js +15 -7
- package/internals/hooks/useDesktopPicker/useDesktopPicker.d.ts +1 -1
- package/internals/hooks/useDesktopPicker/useDesktopPicker.types.d.ts +4 -5
- package/internals/hooks/useField/index.d.ts +1 -1
- package/internals/hooks/useField/useField.d.ts +2 -1
- package/internals/hooks/useField/useField.js +9 -7
- package/internals/hooks/useField/useField.types.d.ts +24 -104
- package/internals/hooks/useField/useField.utils.d.ts +7 -5
- package/internals/hooks/useField/useField.utils.js +68 -50
- package/internals/hooks/useField/useFieldCharacterEditing.d.ts +2 -1
- package/internals/hooks/useField/useFieldState.d.ts +3 -1
- package/internals/hooks/useField/useFieldState.js +88 -62
- package/internals/hooks/useIsLandscape.d.ts +1 -1
- package/internals/hooks/useMobilePicker/useMobilePicker.d.ts +1 -1
- package/internals/hooks/useMobilePicker/useMobilePicker.types.d.ts +4 -5
- package/internals/hooks/usePicker/usePicker.d.ts +1 -2
- package/internals/hooks/usePicker/usePicker.types.d.ts +1 -2
- package/internals/hooks/usePicker/usePickerLayoutProps.d.ts +1 -1
- package/internals/hooks/usePicker/usePickerValue.d.ts +2 -1
- package/internals/hooks/usePicker/usePickerViews.d.ts +1 -1
- package/internals/hooks/useStaticPicker/useStaticPicker.d.ts +1 -1
- package/internals/hooks/useStaticPicker/useStaticPicker.types.d.ts +1 -2
- package/internals/hooks/useViews.d.ts +1 -1
- package/internals/hooks/useViews.js +8 -0
- package/internals/hooks/validation/models.d.ts +1 -1
- package/internals/hooks/validation/useDateTimeValidation.d.ts +3 -3
- package/internals/hooks/validation/useDateValidation.d.ts +2 -2
- package/internals/hooks/validation/useTimeValidation.d.ts +2 -2
- package/internals/index.d.ts +3 -7
- package/internals/index.js +1 -1
- package/internals/models/fields.d.ts +2 -20
- package/internals/models/index.d.ts +0 -1
- package/internals/models/index.js +0 -1
- package/internals/models/muiPickersAdapter.d.ts +1 -10
- package/internals/models/props/basePickerProps.d.ts +3 -3
- package/internals/models/props/tabs.d.ts +1 -1
- package/internals/models/props/toolbar.d.ts +1 -1
- package/internals/utils/time-utils.d.ts +2 -1
- package/internals/utils/utils.d.ts +1 -1
- package/internals/utils/utils.js +3 -3
- package/internals/utils/validation.d.ts +1 -1
- package/internals/utils/valueManagers.d.ts +2 -4
- package/internals/utils/valueManagers.js +8 -8
- package/internals/utils/views.d.ts +1 -1
- package/legacy/AdapterDateFnsJalali/index.js +68 -0
- package/legacy/AdapterLuxon/index.js +12 -3
- package/legacy/index.js +1 -1
- package/legacy/internals/demo/DemoContainer.js +12 -6
- package/legacy/internals/hooks/useField/useField.js +10 -8
- package/legacy/internals/hooks/useField/useField.utils.js +76 -54
- package/legacy/internals/hooks/useField/useFieldState.js +94 -67
- package/legacy/internals/hooks/useViews.js +10 -0
- package/legacy/internals/index.js +1 -1
- package/legacy/internals/models/index.js +0 -1
- package/legacy/internals/utils/utils.js +3 -3
- package/legacy/internals/utils/valueManagers.js +10 -12
- package/legacy/locales/daDK.js +91 -0
- package/legacy/locales/nbNO.js +12 -10
- package/legacy/locales/svSE.js +12 -10
- package/legacy/models/index.js +3 -1
- package/locales/daDK.d.ts +51 -0
- package/locales/daDK.js +59 -0
- package/locales/nbNO.js +8 -10
- package/locales/nlNL.d.ts +4 -4
- package/locales/svSE.js +8 -10
- package/locales/utils/pickersLocaleTextApi.d.ts +2 -1
- package/models/fields.d.ts +117 -0
- package/models/fields.js +1 -0
- package/models/index.d.ts +3 -6
- package/models/index.js +3 -1
- package/models/validation.d.ts +8 -0
- package/models/validation.js +1 -0
- package/models/views.js +1 -0
- package/modern/AdapterDateFnsJalali/index.js +68 -0
- package/modern/AdapterLuxon/index.js +12 -3
- package/modern/index.js +1 -1
- package/modern/internals/demo/DemoContainer.js +15 -7
- package/modern/internals/hooks/useField/useField.js +8 -6
- package/modern/internals/hooks/useField/useField.utils.js +68 -50
- package/modern/internals/hooks/useField/useFieldState.js +88 -62
- package/modern/internals/hooks/useViews.js +8 -0
- package/modern/internals/index.js +1 -1
- package/modern/internals/models/index.js +0 -1
- package/modern/internals/utils/utils.js +3 -3
- package/modern/internals/utils/valueManagers.js +8 -8
- package/modern/locales/daDK.js +56 -0
- package/modern/locales/nbNO.js +8 -10
- package/modern/locales/svSE.js +8 -10
- package/modern/models/fields.js +1 -0
- package/modern/models/index.js +3 -1
- package/modern/models/validation.js +1 -0
- package/modern/models/views.js +1 -0
- package/node/AdapterDateFnsJalali/index.js +68 -0
- package/node/AdapterLuxon/index.js +12 -3
- package/node/index.js +1 -1
- package/node/internals/demo/DemoContainer.js +15 -7
- package/node/internals/hooks/useField/useField.js +8 -6
- package/node/internals/hooks/useField/useField.utils.js +71 -52
- package/node/internals/hooks/useField/useFieldState.js +87 -61
- package/node/internals/hooks/useViews.js +8 -0
- package/node/internals/index.js +0 -6
- package/node/internals/models/index.js +0 -11
- package/node/internals/utils/utils.js +3 -3
- package/node/internals/utils/valueManagers.js +7 -7
- package/node/locales/daDK.js +62 -0
- package/node/locales/nbNO.js +8 -10
- package/node/locales/svSE.js +8 -10
- package/node/models/index.js +33 -0
- package/node/models/validation.js +5 -0
- package/node/models/views.js +5 -0
- package/package.json +1 -1
- package/themeAugmentation/props.d.ts +1 -1
- package/timeViewRenderers/timeViewRenderers.d.ts +1 -1
- /package/{internals/models/views.js → legacy/models/fields.js} +0 -0
- /package/legacy/{internals/models/views.js → models/validation.js} +0 -0
- /package/{modern/internals → legacy}/models/views.js +0 -0
- /package/{internals/models → models}/views.d.ts +0 -0
- /package/node/{internals/models/views.js → models/fields.js} +0 -0
package/modern/locales/svSE.js
CHANGED
|
@@ -16,22 +16,20 @@ const svSEPickers = {
|
|
|
16
16
|
okButtonLabel: 'OK',
|
|
17
17
|
todayButtonLabel: 'Idag',
|
|
18
18
|
// Toolbar titles
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
datePickerToolbarTitle: 'Välj datum',
|
|
20
|
+
dateTimePickerToolbarTitle: 'Välj datum & tid',
|
|
21
|
+
timePickerToolbarTitle: 'Välj tid',
|
|
22
|
+
dateRangePickerToolbarTitle: 'Välj datumintervall',
|
|
24
23
|
// Clock labels
|
|
25
24
|
clockLabelText: (view, time, adapter) => `Select ${view}. ${time === null ? 'Ingen tid vald' : `Vald tid är ${adapter.format(time, 'fullTime')}`}`,
|
|
26
25
|
hoursClockNumberText: hours => `${hours} timmar`,
|
|
27
26
|
minutesClockNumberText: minutes => `${minutes} minuter`,
|
|
28
27
|
secondsClockNumberText: seconds => `${seconds} sekunder`,
|
|
29
28
|
// Calendar labels
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
calendarWeekNumberHeaderLabel: 'Vecka nummer',
|
|
30
|
+
calendarWeekNumberHeaderText: '#',
|
|
31
|
+
calendarWeekNumberAriaLabelText: weekNumber => `Vecka ${weekNumber}`,
|
|
32
|
+
calendarWeekNumberText: weekNumber => `${weekNumber}`,
|
|
35
33
|
// Open picker labels
|
|
36
34
|
openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Välj datum, valt datum är ${utils.format(value, 'fullDate')}` : 'Välj datum',
|
|
37
35
|
openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Välj tid, vald tid är ${utils.format(value, 'fullTime')}` : 'Välj tid',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/modern/models/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -39,6 +39,74 @@ const formatTokenMap = {
|
|
|
39
39
|
// Day of the month
|
|
40
40
|
d: 'day',
|
|
41
41
|
dd: 'day',
|
|
42
|
+
do: 'day',
|
|
43
|
+
// Day of the week
|
|
44
|
+
E: {
|
|
45
|
+
sectionType: 'weekDay',
|
|
46
|
+
contentType: 'letter'
|
|
47
|
+
},
|
|
48
|
+
EE: {
|
|
49
|
+
sectionType: 'weekDay',
|
|
50
|
+
contentType: 'letter'
|
|
51
|
+
},
|
|
52
|
+
EEE: {
|
|
53
|
+
sectionType: 'weekDay',
|
|
54
|
+
contentType: 'letter'
|
|
55
|
+
},
|
|
56
|
+
EEEE: {
|
|
57
|
+
sectionType: 'weekDay',
|
|
58
|
+
contentType: 'letter'
|
|
59
|
+
},
|
|
60
|
+
EEEEE: {
|
|
61
|
+
sectionType: 'weekDay',
|
|
62
|
+
contentType: 'letter'
|
|
63
|
+
},
|
|
64
|
+
i: 'weekDay',
|
|
65
|
+
ii: 'weekDay',
|
|
66
|
+
iii: {
|
|
67
|
+
sectionType: 'weekDay',
|
|
68
|
+
contentType: 'letter'
|
|
69
|
+
},
|
|
70
|
+
iiii: {
|
|
71
|
+
sectionType: 'weekDay',
|
|
72
|
+
contentType: 'letter'
|
|
73
|
+
},
|
|
74
|
+
e: 'weekDay',
|
|
75
|
+
ee: 'weekDay',
|
|
76
|
+
eee: {
|
|
77
|
+
sectionType: 'weekDay',
|
|
78
|
+
contentType: 'letter'
|
|
79
|
+
},
|
|
80
|
+
eeee: {
|
|
81
|
+
sectionType: 'weekDay',
|
|
82
|
+
contentType: 'letter'
|
|
83
|
+
},
|
|
84
|
+
eeeee: {
|
|
85
|
+
sectionType: 'weekDay',
|
|
86
|
+
contentType: 'letter'
|
|
87
|
+
},
|
|
88
|
+
eeeeee: {
|
|
89
|
+
sectionType: 'weekDay',
|
|
90
|
+
contentType: 'letter'
|
|
91
|
+
},
|
|
92
|
+
c: 'weekDay',
|
|
93
|
+
cc: 'weekDay',
|
|
94
|
+
ccc: {
|
|
95
|
+
sectionType: 'weekDay',
|
|
96
|
+
contentType: 'letter'
|
|
97
|
+
},
|
|
98
|
+
cccc: {
|
|
99
|
+
sectionType: 'weekDay',
|
|
100
|
+
contentType: 'letter'
|
|
101
|
+
},
|
|
102
|
+
ccccc: {
|
|
103
|
+
sectionType: 'weekDay',
|
|
104
|
+
contentType: 'letter'
|
|
105
|
+
},
|
|
106
|
+
cccccc: {
|
|
107
|
+
sectionType: 'weekDay',
|
|
108
|
+
contentType: 'letter'
|
|
109
|
+
},
|
|
42
110
|
// Meridiem
|
|
43
111
|
a: 'meridiem',
|
|
44
112
|
aa: 'meridiem',
|
|
@@ -92,12 +92,21 @@ class AdapterLuxon extends _luxon2.default {
|
|
|
92
92
|
if (!_luxon.DateTime.expandFormat) {
|
|
93
93
|
throw Error('Your luxon version does not support `expandFormat`. Consider upgrading it to v3.0.2');
|
|
94
94
|
}
|
|
95
|
+
// Extract escaped section to avoid entending them
|
|
96
|
+
const longFormatRegexp = /''|'(''|[^'])+('|$)|[^']*/g;
|
|
97
|
+
return format.match(longFormatRegexp).map(token => {
|
|
98
|
+
const firstCharacter = token[0];
|
|
99
|
+
if (firstCharacter === "'") {
|
|
100
|
+
return token;
|
|
101
|
+
}
|
|
102
|
+
return _luxon.DateTime.expandFormat(token, {
|
|
103
|
+
locale: this.locale
|
|
104
|
+
});
|
|
105
|
+
}).join('')
|
|
95
106
|
// The returned format can contain `yyyyy` which means year between 4 and 6 digits.
|
|
96
107
|
// This value is supported by luxon parser but not luxon formatter.
|
|
97
108
|
// To avoid conflicts, we replace it by 4 digits which is enough for most use-cases.
|
|
98
|
-
|
|
99
|
-
locale: this.locale
|
|
100
|
-
}).replace('yyyyy', 'yyyy');
|
|
109
|
+
.replace('yyyyy', 'yyyy');
|
|
101
110
|
};
|
|
102
111
|
// Redefined here just to show how it can be written using expandFormat
|
|
103
112
|
this.getFormatHelperText = format => {
|
package/node/index.js
CHANGED
|
@@ -109,14 +109,22 @@ function DemoContainer(props) {
|
|
|
109
109
|
if (childrenTypes.has('UI-view')) {
|
|
110
110
|
// noop
|
|
111
111
|
} else if (childrenTypes.has('single-input-range-field')) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
md: 400
|
|
112
|
+
if (!childrenSupportedSections.has('date-time')) {
|
|
113
|
+
sx = (0, _extends2.default)({}, sx, {
|
|
114
|
+
[`& > .${_TextField.textFieldClasses.root}`]: {
|
|
115
|
+
minWidth: 300
|
|
117
116
|
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
sx = (0, _extends2.default)({}, sx, {
|
|
120
|
+
[`& > .${_TextField.textFieldClasses.root}`]: {
|
|
121
|
+
minWidth: {
|
|
122
|
+
xs: 300,
|
|
123
|
+
md: 400
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
120
128
|
} else if (childrenSupportedSections.has('date-time')) {
|
|
121
129
|
sx = (0, _extends2.default)({}, sx, {
|
|
122
130
|
[`& > .${_TextField.textFieldClasses.root}`]: {
|
|
@@ -32,7 +32,8 @@ const useField = params => {
|
|
|
32
32
|
updateSectionValue,
|
|
33
33
|
updateValueFromValueStr,
|
|
34
34
|
setTempAndroidValueStr,
|
|
35
|
-
sectionsValueBoundaries
|
|
35
|
+
sectionsValueBoundaries,
|
|
36
|
+
placeholder
|
|
36
37
|
} = (0, _useFieldState.useFieldState)(params);
|
|
37
38
|
const {
|
|
38
39
|
applyCharacterEditing,
|
|
@@ -68,7 +69,8 @@ const useField = params => {
|
|
|
68
69
|
const handleRef = (0, _useForkRef.default)(inputRefProp, inputRef);
|
|
69
70
|
const focusTimeoutRef = React.useRef(undefined);
|
|
70
71
|
const theme = (0, _styles.useTheme)();
|
|
71
|
-
const
|
|
72
|
+
const isRTL = theme.direction === 'rtl';
|
|
73
|
+
const sectionOrder = React.useMemo(() => (0, _useField.getSectionOrder)(state.sections, isRTL), [state.sections, isRTL]);
|
|
72
74
|
const syncSelectionFromDOM = () => {
|
|
73
75
|
if (readOnly) {
|
|
74
76
|
setSelectedSections(null);
|
|
@@ -159,7 +161,7 @@ const useField = params => {
|
|
|
159
161
|
if (selectedSectionIndexes.startIndex === 0 && selectedSectionIndexes.endIndex === state.sections.length - 1) {
|
|
160
162
|
keyPressed = cleanValueStr;
|
|
161
163
|
} else {
|
|
162
|
-
const prevValueStr = (0, _useField.cleanString)(fieldValueManager.getValueStrFromSections(state.sections));
|
|
164
|
+
const prevValueStr = (0, _useField.cleanString)(fieldValueManager.getValueStrFromSections(state.sections, isRTL));
|
|
163
165
|
let startOfDiffIndex = -1;
|
|
164
166
|
let endOfDiffIndex = -1;
|
|
165
167
|
for (let i = 0; i < prevValueStr.length; i += 1) {
|
|
@@ -264,7 +266,7 @@ const useField = params => {
|
|
|
264
266
|
}
|
|
265
267
|
const activeSection = state.sections[selectedSectionIndexes.startIndex];
|
|
266
268
|
const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection);
|
|
267
|
-
const newSectionValue = (0, _useField.adjustSectionValue)(utils, activeSection, event.key, sectionsValueBoundaries, activeDateManager.
|
|
269
|
+
const newSectionValue = (0, _useField.adjustSectionValue)(utils, activeSection, event.key, sectionsValueBoundaries, activeDateManager.date);
|
|
268
270
|
updateSectionValue({
|
|
269
271
|
activeSection,
|
|
270
272
|
newSectionValue,
|
|
@@ -330,7 +332,7 @@ const useField = params => {
|
|
|
330
332
|
}
|
|
331
333
|
}, [state.tempValueStrAndroid]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
332
334
|
|
|
333
|
-
const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getValueStrFromSections(state.sections), [state.sections, fieldValueManager, state.tempValueStrAndroid]);
|
|
335
|
+
const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getValueStrFromSections(state.sections, isRTL), [state.sections, fieldValueManager, state.tempValueStrAndroid, isRTL]);
|
|
334
336
|
const inputMode = React.useMemo(() => {
|
|
335
337
|
if (selectedSectionIndexes == null) {
|
|
336
338
|
return 'text';
|
|
@@ -357,7 +359,7 @@ const useField = params => {
|
|
|
357
359
|
setSelectedSections: activeSectionIndex => setSelectedSections(activeSectionIndex)
|
|
358
360
|
}));
|
|
359
361
|
return (0, _extends2.default)({
|
|
360
|
-
placeholder
|
|
362
|
+
placeholder,
|
|
361
363
|
autoComplete: 'off'
|
|
362
364
|
}, otherForwardedProps, {
|
|
363
365
|
value: shouldShowPlaceholder ? '' : valueStr,
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.validateSections = exports.splitFormatIntoSections = exports.mergeDateIntoReferenceDate = exports.isAndroid = exports.getSectionsBoundaries = exports.getSectionOrder = exports.getLetterEditingOptions = exports.getDaysInWeekStr = exports.getDateSectionConfigFromFormatToken = exports.getDateFromDateSections = exports.doesSectionHaveLeadingZeros = exports.createDateStrForInputFromSections = exports.cleanString = exports.cleanDigitSectionValue = exports.
|
|
7
|
+
exports.validateSections = exports.splitFormatIntoSections = exports.mergeDateIntoReferenceDate = exports.isAndroid = exports.getSectionsBoundaries = exports.getSectionVisibleValue = exports.getSectionOrder = exports.getLetterEditingOptions = exports.getDaysInWeekStr = exports.getDateSectionConfigFromFormatToken = exports.getDateFromDateSections = exports.doesSectionHaveLeadingZeros = exports.createDateStrForInputFromSections = exports.cleanString = exports.cleanDigitSectionValue = exports.clampDaySectionIfPossible = exports.changeSectionValueFormat = exports.adjustSectionValue = exports.addPositionPropertiesToSections = void 0;
|
|
8
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
9
|
const getDateSectionConfigFromFormatToken = (utils, formatToken) => {
|
|
10
10
|
const config = utils.formatTokenMap[formatToken];
|
|
@@ -159,33 +159,33 @@ const adjustSectionValue = (utils, section, keyCode, sectionsValueBoundaries, ac
|
|
|
159
159
|
return adjustLetterSection();
|
|
160
160
|
};
|
|
161
161
|
exports.adjustSectionValue = adjustSectionValue;
|
|
162
|
-
const getSectionVisibleValue = (section,
|
|
163
|
-
|
|
162
|
+
const getSectionVisibleValue = (section, target) => {
|
|
163
|
+
let value = section.value || section.placeholder;
|
|
164
164
|
|
|
165
165
|
// In the input, we add an empty character at the end of each section without leading zeros.
|
|
166
166
|
// This makes sure that `onChange` will always be fired.
|
|
167
167
|
// Otherwise, when your input value equals `1/dd/yyyy` (format `M/DD/YYYY` on DayJs),
|
|
168
168
|
// If you press `1`, on the first section, the new value is also `1/dd/yyyy`,
|
|
169
169
|
// So the browser will not fire the input `onChange`.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return `\u2068${value}\u200e\u2069`;
|
|
170
|
+
const shouldAddInvisibleSpace = ['input-rtl', 'input-ltr'].includes(target) && section.contentType === 'digit' && !section.hasLeadingZeros && value.length === 1;
|
|
171
|
+
if (shouldAddInvisibleSpace) {
|
|
172
|
+
value = `${value}\u200e`;
|
|
174
173
|
}
|
|
175
|
-
if (
|
|
176
|
-
|
|
174
|
+
if (target === 'input-rtl') {
|
|
175
|
+
value = `\u2068${value}\u2069`;
|
|
177
176
|
}
|
|
178
177
|
return value;
|
|
179
178
|
};
|
|
179
|
+
exports.getSectionVisibleValue = getSectionVisibleValue;
|
|
180
180
|
const cleanString = dirtyString => dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
|
|
181
181
|
exports.cleanString = cleanString;
|
|
182
|
-
const addPositionPropertiesToSections = sections => {
|
|
182
|
+
const addPositionPropertiesToSections = (sections, isRTL) => {
|
|
183
183
|
let position = 0;
|
|
184
|
-
let positionInInput = 1;
|
|
184
|
+
let positionInInput = isRTL ? 1 : 0;
|
|
185
185
|
const newSections = [];
|
|
186
186
|
for (let i = 0; i < sections.length; i += 1) {
|
|
187
187
|
const section = sections[i];
|
|
188
|
-
const renderedValue = getSectionVisibleValue(section,
|
|
188
|
+
const renderedValue = getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr');
|
|
189
189
|
const sectionStr = `${section.startSeparator}${renderedValue}${section.endSeparator}`;
|
|
190
190
|
const sectionLength = cleanString(sectionStr).length;
|
|
191
191
|
const sectionLengthInInput = sectionStr.length;
|
|
@@ -333,10 +333,6 @@ const splitFormatIntoSections = (utils, localeText, format, date) => {
|
|
|
333
333
|
if (token === '') {
|
|
334
334
|
return null;
|
|
335
335
|
}
|
|
336
|
-
const expandedToken = utils.expandFormat(token);
|
|
337
|
-
if (expandedToken !== token) {
|
|
338
|
-
return expandedToken;
|
|
339
|
-
}
|
|
340
336
|
const sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
|
|
341
337
|
const sectionValue = date == null || !utils.isValid(date) ? '' : utils.formatByString(date, token);
|
|
342
338
|
const hasLeadingZeros = doesSectionHaveLeadingZeros(utils, sectionConfig.contentType, sectionConfig.type, token);
|
|
@@ -351,39 +347,50 @@ const splitFormatIntoSections = (utils, localeText, format, date) => {
|
|
|
351
347
|
}));
|
|
352
348
|
return null;
|
|
353
349
|
};
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
350
|
+
|
|
351
|
+
// Expand the provided format
|
|
352
|
+
let formatExpansionOverflow = 10;
|
|
353
|
+
let prevFormat = format;
|
|
354
|
+
let nextFormat = utils.expandFormat(format);
|
|
355
|
+
while (nextFormat !== prevFormat) {
|
|
356
|
+
prevFormat = nextFormat;
|
|
357
|
+
nextFormat = utils.expandFormat(prevFormat);
|
|
358
|
+
formatExpansionOverflow -= 1;
|
|
359
|
+
if (formatExpansionOverflow < 0) {
|
|
360
|
+
throw new Error('MUI: The format expansion seems to be enter in an infinite loop. Please open an issue with the format passed to the picker component');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
const expandedFormat = nextFormat;
|
|
364
|
+
|
|
365
|
+
// Get start/end indexes of escaped sections
|
|
366
|
+
const escapedParts = getEscapedPartsFromFormat(utils, expandedFormat);
|
|
367
|
+
|
|
368
|
+
// This RegExp test if the beginning of a string correspond to a supported token
|
|
369
|
+
const isTokenStartRegExp = new RegExp(`^(${Object.keys(utils.formatTokenMap).join('|')})`);
|
|
370
|
+
let currentTokenValue = '';
|
|
371
|
+
for (let i = 0; i < expandedFormat.length; i += 1) {
|
|
372
|
+
const escapedPartOfCurrentChar = escapedParts.find(escapeIndex => escapeIndex.start <= i && escapeIndex.end >= i);
|
|
373
|
+
const char = expandedFormat[i];
|
|
374
|
+
const isEscapedChar = escapedPartOfCurrentChar != null;
|
|
375
|
+
const potentialToken = `${currentTokenValue}${expandedFormat.slice(i)}`;
|
|
376
|
+
if (!isEscapedChar && char.match(/([A-Za-z]+)/) && isTokenStartRegExp.test(potentialToken)) {
|
|
377
|
+
currentTokenValue += char;
|
|
378
|
+
} else {
|
|
379
|
+
// If we are on the opening or closing character of an escaped part of the format,
|
|
380
|
+
// Then we ignore this character.
|
|
381
|
+
const isEscapeBoundary = isEscapedChar && escapedPartOfCurrentChar?.start === i || escapedPartOfCurrentChar?.end === i;
|
|
382
|
+
if (!isEscapeBoundary) {
|
|
383
|
+
commitToken(currentTokenValue);
|
|
384
|
+
currentTokenValue = '';
|
|
385
|
+
if (sections.length === 0) {
|
|
386
|
+
startSeparator += char;
|
|
387
|
+
} else {
|
|
388
|
+
sections[sections.length - 1].endSeparator += char;
|
|
378
389
|
}
|
|
379
390
|
}
|
|
380
391
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
splitFormat(expandedToken);
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
splitFormat(format);
|
|
392
|
+
}
|
|
393
|
+
commitToken(currentTokenValue);
|
|
387
394
|
return sections.map(section => {
|
|
388
395
|
const cleanSeparator = separator => {
|
|
389
396
|
let cleanedSeparator = separator;
|
|
@@ -418,7 +425,7 @@ const getDateFromDateSections = (utils, sections) => {
|
|
|
418
425
|
const shouldSkip = shouldSkipWeekDays && section.type === 'weekDay';
|
|
419
426
|
if (!shouldSkip) {
|
|
420
427
|
sectionFormats.push(section.format);
|
|
421
|
-
sectionValues.push(getSectionVisibleValue(section,
|
|
428
|
+
sectionValues.push(getSectionVisibleValue(section, 'non-input'));
|
|
422
429
|
}
|
|
423
430
|
}
|
|
424
431
|
const formatWithoutSeparator = sectionFormats.join(' ');
|
|
@@ -426,15 +433,19 @@ const getDateFromDateSections = (utils, sections) => {
|
|
|
426
433
|
return utils.parse(dateWithoutSeparatorStr, formatWithoutSeparator);
|
|
427
434
|
};
|
|
428
435
|
exports.getDateFromDateSections = getDateFromDateSections;
|
|
429
|
-
const createDateStrForInputFromSections = sections => {
|
|
430
|
-
const
|
|
436
|
+
const createDateStrForInputFromSections = (sections, isRTL) => {
|
|
437
|
+
const formattedSections = sections.map(section => `${section.startSeparator}${getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr')}${section.endSeparator}`);
|
|
438
|
+
const dateStr = formattedSections.join('');
|
|
439
|
+
if (!isRTL) {
|
|
440
|
+
return dateStr;
|
|
441
|
+
}
|
|
431
442
|
|
|
432
443
|
// \u2066: start left-to-right isolation
|
|
433
444
|
// \u2067: start right-to-left isolation
|
|
434
445
|
// \u2068: start first strong character isolation
|
|
435
446
|
// \u2069: pop isolation
|
|
436
447
|
// wrap into an isolated group such that separators can split the string in smaller ones by adding \u2069\u2068
|
|
437
|
-
return `\u2066${
|
|
448
|
+
return `\u2066${dateStr}\u2069`;
|
|
438
449
|
};
|
|
439
450
|
exports.createDateStrForInputFromSections = createDateStrForInputFromSections;
|
|
440
451
|
const getSectionsBoundaries = utils => {
|
|
@@ -606,7 +617,15 @@ const mergeDateIntoReferenceDate = (utils, dateToTransferFrom, sections, referen
|
|
|
606
617
|
exports.mergeDateIntoReferenceDate = mergeDateIntoReferenceDate;
|
|
607
618
|
const isAndroid = () => navigator.userAgent.toLowerCase().indexOf('android') > -1;
|
|
608
619
|
exports.isAndroid = isAndroid;
|
|
609
|
-
const
|
|
620
|
+
const clampDaySectionIfPossible = (utils, sections, sectionsValueBoundaries) => {
|
|
621
|
+
// We can only clamp the day value if:
|
|
622
|
+
// 1. if all the sections are filled (except the week day section which can be empty)
|
|
623
|
+
// 2. there is a day section
|
|
624
|
+
const canClamp = sections.every(section => section.type === 'weekDay' || section.value !== '') && sections.some(section => section.type === 'day');
|
|
625
|
+
if (!canClamp) {
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
|
|
610
629
|
// We try to generate a valid date representing the start of the month of the invalid date typed by the user.
|
|
611
630
|
const sectionsForStartOfMonth = sections.map(section => {
|
|
612
631
|
if (section.type !== 'day') {
|
|
@@ -646,7 +665,7 @@ const clampDaySection = (utils, sections, sectionsValueBoundaries) => {
|
|
|
646
665
|
});
|
|
647
666
|
});
|
|
648
667
|
};
|
|
649
|
-
exports.
|
|
668
|
+
exports.clampDaySectionIfPossible = clampDaySectionIfPossible;
|
|
650
669
|
const getSectionOrder = (sections, isRTL) => {
|
|
651
670
|
const neighbors = {};
|
|
652
671
|
if (!isRTL) {
|