rn-grid-date-time-picker 1.0.0 → 1.2.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/CHANGELOG.md +86 -0
- package/README.md +100 -638
- package/lib/commonjs/adapters/utcMidnight.js +15 -6
- package/lib/commonjs/adapters/utcMidnight.js.map +1 -1
- package/lib/commonjs/components/DateTimePicker.js +484 -85
- package/lib/commonjs/components/DateTimePicker.js.map +1 -1
- package/lib/commonjs/components/calendar/Calendar.js +21 -7
- package/lib/commonjs/components/calendar/Calendar.js.map +1 -1
- package/lib/commonjs/components/calendar/CalendarHeader.js +46 -6
- package/lib/commonjs/components/calendar/CalendarHeader.js.map +1 -1
- package/lib/commonjs/components/calendar/CalendarSwitch.js +150 -0
- package/lib/commonjs/components/calendar/CalendarSwitch.js.map +1 -0
- package/lib/commonjs/components/calendar/DayCell.js +8 -3
- package/lib/commonjs/components/calendar/DayCell.js.map +1 -1
- package/lib/commonjs/components/calendar/DayGrid.js +13 -2
- package/lib/commonjs/components/calendar/DayGrid.js.map +1 -1
- package/lib/commonjs/components/calendar/PeriodGrid.js +3 -1
- package/lib/commonjs/components/calendar/PeriodGrid.js.map +1 -1
- package/lib/commonjs/components/calendar/calendarStyles.js +3 -2
- package/lib/commonjs/components/calendar/calendarStyles.js.map +1 -1
- package/lib/commonjs/components/calendar/localeNames.js +46 -24
- package/lib/commonjs/components/calendar/localeNames.js.map +1 -1
- package/lib/commonjs/components/calendar/selection.js +9 -1
- package/lib/commonjs/components/calendar/selection.js.map +1 -1
- package/lib/commonjs/components/container/DefaultSheet.js +42 -11
- package/lib/commonjs/components/container/DefaultSheet.js.map +1 -1
- package/lib/commonjs/components/container/PickerContainer.js +4 -0
- package/lib/commonjs/components/container/PickerContainer.js.map +1 -1
- package/lib/commonjs/components/container/PickerLayout.js +1 -1
- package/lib/commonjs/components/container/PickerLayout.js.map +1 -1
- package/lib/commonjs/components/container/containerStyles.js +12 -4
- package/lib/commonjs/components/container/containerStyles.js.map +1 -1
- package/lib/commonjs/components/field/RangeFields.js +5 -1
- package/lib/commonjs/components/field/RangeFields.js.map +1 -1
- package/lib/commonjs/components/field/SegmentedInput.js +8 -3
- package/lib/commonjs/components/field/SegmentedInput.js.map +1 -1
- package/lib/commonjs/components/field/ValueField.js +64 -8
- package/lib/commonjs/components/field/ValueField.js.map +1 -1
- package/lib/commonjs/components/field/fieldStyles.js +17 -0
- package/lib/commonjs/components/field/fieldStyles.js.map +1 -1
- package/lib/commonjs/components/field/fieldText.js +29 -13
- package/lib/commonjs/components/field/fieldText.js.map +1 -1
- package/lib/commonjs/components/hooks/useBottomInset.js +32 -0
- package/lib/commonjs/components/hooks/useBottomInset.js.map +1 -0
- package/lib/commonjs/components/hooks/useKeyboardFold.js +36 -13
- package/lib/commonjs/components/hooks/useKeyboardFold.js.map +1 -1
- package/lib/commonjs/components/hooks/useOpenPicker.js +39 -17
- package/lib/commonjs/components/hooks/useOpenPicker.js.map +1 -1
- package/lib/commonjs/components/hooks/useTypedSegments.js +6 -2
- package/lib/commonjs/components/hooks/useTypedSegments.js.map +1 -1
- package/lib/commonjs/components/theme/defaultStrings.js +13 -3
- package/lib/commonjs/components/theme/defaultStrings.js.map +1 -1
- package/lib/commonjs/components/theme/direction.js +17 -0
- package/lib/commonjs/components/theme/direction.js.map +1 -0
- package/lib/commonjs/components/theme/numerals.js +16 -0
- package/lib/commonjs/components/theme/numerals.js.map +1 -0
- package/lib/commonjs/components/theme/styleKeys.js +10 -2
- package/lib/commonjs/components/theme/styleKeys.js.map +1 -1
- package/lib/commonjs/components/theme/tokens.js +4 -0
- package/lib/commonjs/components/theme/tokens.js.map +1 -1
- package/lib/commonjs/components/time/TimeRow.js +10 -2
- package/lib/commonjs/components/time/TimeRow.js.map +1 -1
- package/lib/commonjs/components/time/TypedTime.js +3 -1
- package/lib/commonjs/components/time/TypedTime.js.map +1 -1
- package/lib/commonjs/components/time/Wheel.js +20 -3
- package/lib/commonjs/components/time/Wheel.js.map +1 -1
- package/lib/commonjs/components/time/timeStyles.js +4 -5
- package/lib/commonjs/components/time/timeStyles.js.map +1 -1
- package/lib/commonjs/components/types.js +10 -0
- package/lib/commonjs/components/types.js.map +1 -1
- package/lib/commonjs/core/calendarSystem.js +123 -22
- package/lib/commonjs/core/calendarSystem.js.map +1 -1
- package/lib/commonjs/core/digits.js +25 -0
- package/lib/commonjs/core/digits.js.map +1 -0
- package/lib/commonjs/core/draft.js +31 -10
- package/lib/commonjs/core/draft.js.map +1 -1
- package/lib/commonjs/core/locale.js +20 -4
- package/lib/commonjs/core/locale.js.map +1 -1
- package/lib/commonjs/core/numerals.js +46 -0
- package/lib/commonjs/core/numerals.js.map +1 -0
- package/lib/commonjs/core/segmentEditor.js +9 -0
- package/lib/commonjs/core/segmentEditor.js.map +1 -1
- package/lib/commonjs/core/segments.js +2 -11
- package/lib/commonjs/core/segments.js.map +1 -1
- package/lib/commonjs/core/selectionRules.js +2 -1
- package/lib/commonjs/core/selectionRules.js.map +1 -1
- package/lib/commonjs/core/timeEntry.js +7 -91
- package/lib/commonjs/core/timeEntry.js.map +1 -1
- package/lib/commonjs/icons/index.js +5 -1
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/index.js +20 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/adapters/utcMidnight.js +14 -5
- package/lib/module/adapters/utcMidnight.js.map +1 -1
- package/lib/module/components/DateTimePicker.js +490 -91
- package/lib/module/components/DateTimePicker.js.map +1 -1
- package/lib/module/components/calendar/Calendar.js +25 -11
- package/lib/module/components/calendar/Calendar.js.map +1 -1
- package/lib/module/components/calendar/CalendarHeader.js +47 -7
- package/lib/module/components/calendar/CalendarHeader.js.map +1 -1
- package/lib/module/components/calendar/CalendarSwitch.js +145 -0
- package/lib/module/components/calendar/CalendarSwitch.js.map +1 -0
- package/lib/module/components/calendar/DayCell.js +8 -3
- package/lib/module/components/calendar/DayCell.js.map +1 -1
- package/lib/module/components/calendar/DayGrid.js +14 -3
- package/lib/module/components/calendar/DayGrid.js.map +1 -1
- package/lib/module/components/calendar/PeriodGrid.js +3 -1
- package/lib/module/components/calendar/PeriodGrid.js.map +1 -1
- package/lib/module/components/calendar/calendarStyles.js +3 -2
- package/lib/module/components/calendar/calendarStyles.js.map +1 -1
- package/lib/module/components/calendar/localeNames.js +46 -24
- package/lib/module/components/calendar/localeNames.js.map +1 -1
- package/lib/module/components/calendar/selection.js +7 -0
- package/lib/module/components/calendar/selection.js.map +1 -1
- package/lib/module/components/container/DefaultSheet.js +42 -12
- package/lib/module/components/container/DefaultSheet.js.map +1 -1
- package/lib/module/components/container/PickerContainer.js +4 -0
- package/lib/module/components/container/PickerContainer.js.map +1 -1
- package/lib/module/components/container/PickerLayout.js +1 -1
- package/lib/module/components/container/PickerLayout.js.map +1 -1
- package/lib/module/components/container/containerStyles.js +11 -3
- package/lib/module/components/container/containerStyles.js.map +1 -1
- package/lib/module/components/field/RangeFields.js +5 -1
- package/lib/module/components/field/RangeFields.js.map +1 -1
- package/lib/module/components/field/SegmentedInput.js +8 -3
- package/lib/module/components/field/SegmentedInput.js.map +1 -1
- package/lib/module/components/field/ValueField.js +66 -10
- package/lib/module/components/field/ValueField.js.map +1 -1
- package/lib/module/components/field/fieldStyles.js +17 -0
- package/lib/module/components/field/fieldStyles.js.map +1 -1
- package/lib/module/components/field/fieldText.js +28 -11
- package/lib/module/components/field/fieldText.js.map +1 -1
- package/lib/module/components/hooks/useBottomInset.js +27 -0
- package/lib/module/components/hooks/useBottomInset.js.map +1 -0
- package/lib/module/components/hooks/useKeyboardFold.js +33 -12
- package/lib/module/components/hooks/useKeyboardFold.js.map +1 -1
- package/lib/module/components/hooks/useOpenPicker.js +39 -17
- package/lib/module/components/hooks/useOpenPicker.js.map +1 -1
- package/lib/module/components/hooks/useTypedSegments.js +6 -2
- package/lib/module/components/hooks/useTypedSegments.js.map +1 -1
- package/lib/module/components/theme/defaultStrings.js +11 -2
- package/lib/module/components/theme/defaultStrings.js.map +1 -1
- package/lib/module/components/theme/direction.js +13 -0
- package/lib/module/components/theme/direction.js.map +1 -0
- package/lib/module/components/theme/numerals.js +12 -0
- package/lib/module/components/theme/numerals.js.map +1 -0
- package/lib/module/components/theme/styleKeys.js +10 -2
- package/lib/module/components/theme/styleKeys.js.map +1 -1
- package/lib/module/components/theme/tokens.js +4 -0
- package/lib/module/components/theme/tokens.js.map +1 -1
- package/lib/module/components/time/TimeRow.js +11 -3
- package/lib/module/components/time/TimeRow.js.map +1 -1
- package/lib/module/components/time/TypedTime.js +3 -1
- package/lib/module/components/time/TypedTime.js.map +1 -1
- package/lib/module/components/time/Wheel.js +18 -2
- package/lib/module/components/time/Wheel.js.map +1 -1
- package/lib/module/components/time/timeStyles.js +4 -5
- package/lib/module/components/time/timeStyles.js.map +1 -1
- package/lib/module/components/types.js +10 -0
- package/lib/module/components/types.js.map +1 -1
- package/lib/module/core/calendarSystem.js +118 -19
- package/lib/module/core/calendarSystem.js.map +1 -1
- package/lib/module/core/digits.js +20 -0
- package/lib/module/core/digits.js.map +1 -0
- package/lib/module/core/draft.js +29 -9
- package/lib/module/core/draft.js.map +1 -1
- package/lib/module/core/locale.js +18 -3
- package/lib/module/core/locale.js.map +1 -1
- package/lib/module/core/numerals.js +39 -0
- package/lib/module/core/numerals.js.map +1 -0
- package/lib/module/core/segmentEditor.js +9 -0
- package/lib/module/core/segmentEditor.js.map +1 -1
- package/lib/module/core/segments.js +0 -8
- package/lib/module/core/segments.js.map +1 -1
- package/lib/module/core/selectionRules.js +2 -1
- package/lib/module/core/selectionRules.js.map +1 -1
- package/lib/module/core/timeEntry.js +7 -89
- package/lib/module/core/timeEntry.js.map +1 -1
- package/lib/module/icons/index.js +5 -1
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/adapters/utcMidnight.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/DateTimePicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/Calendar.d.ts +8 -4
- package/lib/typescript/commonjs/src/components/calendar/Calendar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/CalendarHeader.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/CalendarSwitch.d.ts +26 -0
- package/lib/typescript/commonjs/src/components/calendar/CalendarSwitch.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/components/calendar/DayCell.d.ts +1 -1
- package/lib/typescript/commonjs/src/components/calendar/DayCell.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/DayGrid.d.ts +2 -0
- package/lib/typescript/commonjs/src/components/calendar/DayGrid.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/PeriodGrid.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts +1 -1
- package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/localeNames.d.ts +8 -3
- package/lib/typescript/commonjs/src/components/calendar/localeNames.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/calendar/selection.d.ts +2 -0
- package/lib/typescript/commonjs/src/components/calendar/selection.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/container/DefaultSheet.d.ts +10 -2
- package/lib/typescript/commonjs/src/components/container/DefaultSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/container/PickerContainer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/container/containerStyles.d.ts +6 -0
- package/lib/typescript/commonjs/src/components/container/containerStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/RangeFields.d.ts +5 -0
- package/lib/typescript/commonjs/src/components/field/RangeFields.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/SegmentedInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/ValueField.d.ts +7 -0
- package/lib/typescript/commonjs/src/components/field/ValueField.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/fieldStyles.d.ts +15 -0
- package/lib/typescript/commonjs/src/components/field/fieldStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/fieldText.d.ts +14 -5
- package/lib/typescript/commonjs/src/components/field/fieldText.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/hooks/useBottomInset.d.ts +8 -0
- package/lib/typescript/commonjs/src/components/hooks/useBottomInset.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/components/hooks/useKeyboardFold.d.ts +10 -2
- package/lib/typescript/commonjs/src/components/hooks/useKeyboardFold.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/hooks/useOpenPicker.d.ts +2 -1
- package/lib/typescript/commonjs/src/components/hooks/useOpenPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/hooks/useTypedSegments.d.ts +3 -2
- package/lib/typescript/commonjs/src/components/hooks/useTypedSegments.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/theme/defaultStrings.d.ts +13 -2
- package/lib/typescript/commonjs/src/components/theme/defaultStrings.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/theme/direction.d.ts +8 -0
- package/lib/typescript/commonjs/src/components/theme/direction.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/components/theme/numerals.d.ts +7 -0
- package/lib/typescript/commonjs/src/components/theme/numerals.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/components/theme/styleKeys.d.ts +1 -1
- package/lib/typescript/commonjs/src/components/theme/styleKeys.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/theme/tokens.d.ts +3 -1
- package/lib/typescript/commonjs/src/components/theme/tokens.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/time/TimeRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/time/TypedTime.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/time/Wheel.d.ts +5 -0
- package/lib/typescript/commonjs/src/components/time/Wheel.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/time/timeStyles.d.ts +0 -2
- package/lib/typescript/commonjs/src/components/time/timeStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/types.d.ts +84 -4
- package/lib/typescript/commonjs/src/components/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/calendarSystem.d.ts +20 -5
- package/lib/typescript/commonjs/src/core/calendarSystem.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/digits.d.ts +3 -0
- package/lib/typescript/commonjs/src/core/digits.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/core/draft.d.ts +12 -1
- package/lib/typescript/commonjs/src/core/draft.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/locale.d.ts +6 -0
- package/lib/typescript/commonjs/src/core/locale.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/numerals.d.ts +15 -0
- package/lib/typescript/commonjs/src/core/numerals.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/core/segmentEditor.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/segments.d.ts +0 -2
- package/lib/typescript/commonjs/src/core/segments.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/selectionRules.d.ts +3 -2
- package/lib/typescript/commonjs/src/core/selectionRules.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/timeEntry.d.ts +4 -24
- package/lib/typescript/commonjs/src/core/timeEntry.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +7 -3
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/adapters/utcMidnight.d.ts.map +1 -1
- package/lib/typescript/module/src/components/DateTimePicker.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/Calendar.d.ts +8 -4
- package/lib/typescript/module/src/components/calendar/Calendar.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/CalendarHeader.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/CalendarSwitch.d.ts +26 -0
- package/lib/typescript/module/src/components/calendar/CalendarSwitch.d.ts.map +1 -0
- package/lib/typescript/module/src/components/calendar/DayCell.d.ts +1 -1
- package/lib/typescript/module/src/components/calendar/DayCell.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/DayGrid.d.ts +2 -0
- package/lib/typescript/module/src/components/calendar/DayGrid.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/PeriodGrid.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts +1 -1
- package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/localeNames.d.ts +8 -3
- package/lib/typescript/module/src/components/calendar/localeNames.d.ts.map +1 -1
- package/lib/typescript/module/src/components/calendar/selection.d.ts +2 -0
- package/lib/typescript/module/src/components/calendar/selection.d.ts.map +1 -1
- package/lib/typescript/module/src/components/container/DefaultSheet.d.ts +10 -2
- package/lib/typescript/module/src/components/container/DefaultSheet.d.ts.map +1 -1
- package/lib/typescript/module/src/components/container/PickerContainer.d.ts.map +1 -1
- package/lib/typescript/module/src/components/container/containerStyles.d.ts +6 -0
- package/lib/typescript/module/src/components/container/containerStyles.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/RangeFields.d.ts +5 -0
- package/lib/typescript/module/src/components/field/RangeFields.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/SegmentedInput.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/ValueField.d.ts +7 -0
- package/lib/typescript/module/src/components/field/ValueField.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/fieldStyles.d.ts +15 -0
- package/lib/typescript/module/src/components/field/fieldStyles.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/fieldText.d.ts +14 -5
- package/lib/typescript/module/src/components/field/fieldText.d.ts.map +1 -1
- package/lib/typescript/module/src/components/hooks/useBottomInset.d.ts +8 -0
- package/lib/typescript/module/src/components/hooks/useBottomInset.d.ts.map +1 -0
- package/lib/typescript/module/src/components/hooks/useKeyboardFold.d.ts +10 -2
- package/lib/typescript/module/src/components/hooks/useKeyboardFold.d.ts.map +1 -1
- package/lib/typescript/module/src/components/hooks/useOpenPicker.d.ts +2 -1
- package/lib/typescript/module/src/components/hooks/useOpenPicker.d.ts.map +1 -1
- package/lib/typescript/module/src/components/hooks/useTypedSegments.d.ts +3 -2
- package/lib/typescript/module/src/components/hooks/useTypedSegments.d.ts.map +1 -1
- package/lib/typescript/module/src/components/theme/defaultStrings.d.ts +13 -2
- package/lib/typescript/module/src/components/theme/defaultStrings.d.ts.map +1 -1
- package/lib/typescript/module/src/components/theme/direction.d.ts +8 -0
- package/lib/typescript/module/src/components/theme/direction.d.ts.map +1 -0
- package/lib/typescript/module/src/components/theme/numerals.d.ts +7 -0
- package/lib/typescript/module/src/components/theme/numerals.d.ts.map +1 -0
- package/lib/typescript/module/src/components/theme/styleKeys.d.ts +1 -1
- package/lib/typescript/module/src/components/theme/styleKeys.d.ts.map +1 -1
- package/lib/typescript/module/src/components/theme/tokens.d.ts +3 -1
- package/lib/typescript/module/src/components/theme/tokens.d.ts.map +1 -1
- package/lib/typescript/module/src/components/time/TimeRow.d.ts.map +1 -1
- package/lib/typescript/module/src/components/time/TypedTime.d.ts.map +1 -1
- package/lib/typescript/module/src/components/time/Wheel.d.ts +5 -0
- package/lib/typescript/module/src/components/time/Wheel.d.ts.map +1 -1
- package/lib/typescript/module/src/components/time/timeStyles.d.ts +0 -2
- package/lib/typescript/module/src/components/time/timeStyles.d.ts.map +1 -1
- package/lib/typescript/module/src/components/types.d.ts +84 -4
- package/lib/typescript/module/src/components/types.d.ts.map +1 -1
- package/lib/typescript/module/src/core/calendarSystem.d.ts +20 -5
- package/lib/typescript/module/src/core/calendarSystem.d.ts.map +1 -1
- package/lib/typescript/module/src/core/digits.d.ts +3 -0
- package/lib/typescript/module/src/core/digits.d.ts.map +1 -0
- package/lib/typescript/module/src/core/draft.d.ts +12 -1
- package/lib/typescript/module/src/core/draft.d.ts.map +1 -1
- package/lib/typescript/module/src/core/locale.d.ts +6 -0
- package/lib/typescript/module/src/core/locale.d.ts.map +1 -1
- package/lib/typescript/module/src/core/numerals.d.ts +15 -0
- package/lib/typescript/module/src/core/numerals.d.ts.map +1 -0
- package/lib/typescript/module/src/core/segmentEditor.d.ts.map +1 -1
- package/lib/typescript/module/src/core/segments.d.ts +0 -2
- package/lib/typescript/module/src/core/segments.d.ts.map +1 -1
- package/lib/typescript/module/src/core/selectionRules.d.ts +3 -2
- package/lib/typescript/module/src/core/selectionRules.d.ts.map +1 -1
- package/lib/typescript/module/src/core/timeEntry.d.ts +4 -24
- package/lib/typescript/module/src/core/timeEntry.d.ts.map +1 -1
- package/lib/typescript/module/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +7 -3
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +22 -7
- package/src/adapters/utcMidnight.ts +14 -5
- package/src/components/DateTimePicker.tsx +607 -108
- package/src/components/calendar/Calendar.tsx +54 -16
- package/src/components/calendar/CalendarHeader.tsx +41 -9
- package/src/components/calendar/CalendarSwitch.tsx +170 -0
- package/src/components/calendar/DayCell.tsx +16 -4
- package/src/components/calendar/DayGrid.tsx +18 -3
- package/src/components/calendar/PeriodGrid.tsx +3 -1
- package/src/components/calendar/calendarStyles.ts +3 -2
- package/src/components/calendar/localeNames.ts +52 -22
- package/src/components/calendar/selection.ts +8 -0
- package/src/components/container/DefaultSheet.tsx +60 -14
- package/src/components/container/PickerContainer.tsx +4 -0
- package/src/components/container/PickerLayout.tsx +1 -1
- package/src/components/container/containerStyles.ts +12 -3
- package/src/components/field/RangeFields.tsx +12 -2
- package/src/components/field/SegmentedInput.tsx +8 -3
- package/src/components/field/ValueField.tsx +94 -18
- package/src/components/field/fieldStyles.ts +6 -0
- package/src/components/field/fieldText.ts +68 -15
- package/src/components/hooks/useBottomInset.ts +33 -0
- package/src/components/hooks/useKeyboardFold.ts +41 -13
- package/src/components/hooks/useOpenPicker.ts +41 -18
- package/src/components/hooks/useTypedSegments.ts +7 -3
- package/src/components/theme/defaultStrings.ts +29 -4
- package/src/components/theme/direction.ts +12 -0
- package/src/components/theme/numerals.ts +11 -0
- package/src/components/theme/styleKeys.ts +18 -1
- package/src/components/theme/tokens.ts +5 -1
- package/src/components/time/TimeRow.tsx +23 -3
- package/src/components/time/TypedTime.tsx +3 -1
- package/src/components/time/Wheel.tsx +19 -5
- package/src/components/time/timeStyles.ts +2 -3
- package/src/components/types.ts +86 -4
- package/src/core/calendarSystem.ts +145 -21
- package/src/core/digits.ts +21 -0
- package/src/core/draft.ts +41 -13
- package/src/core/locale.ts +20 -3
- package/src/core/numerals.ts +35 -0
- package/src/core/segmentEditor.ts +13 -0
- package/src/core/segments.ts +0 -8
- package/src/core/selectionRules.ts +3 -2
- package/src/core/timeEntry.ts +6 -96
- package/src/icons/index.tsx +3 -1
- package/src/index.tsx +12 -2
|
@@ -6,16 +6,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _luxon = require("luxon");
|
|
9
|
+
var _reactNative = require("react-native");
|
|
9
10
|
var _index = require("../adapters/index.js");
|
|
10
11
|
var _calendarDate = require("../core/calendarDate.js");
|
|
11
12
|
var _constraints = require("../core/constraints.js");
|
|
12
13
|
var _draft = require("../core/draft.js");
|
|
13
14
|
var _calendarSystem = require("../core/calendarSystem.js");
|
|
14
15
|
var _locale = require("../core/locale.js");
|
|
16
|
+
var _numerals = require("../core/numerals.js");
|
|
15
17
|
var _selectionRules = require("../core/selectionRules.js");
|
|
16
18
|
var _timeEntry = require("../core/timeEntry.js");
|
|
17
19
|
var _Calendar = _interopRequireDefault(require("./calendar/Calendar.js"));
|
|
20
|
+
var _CalendarSwitch = _interopRequireDefault(require("./calendar/CalendarSwitch.js"));
|
|
18
21
|
var _localeNames = require("./calendar/localeNames.js");
|
|
22
|
+
var _direction = require("./theme/direction.js");
|
|
23
|
+
var _numerals2 = require("./theme/numerals.js");
|
|
24
|
+
var _selection = require("./calendar/selection.js");
|
|
19
25
|
var _PickerContainer = _interopRequireDefault(require("./container/PickerContainer.js"));
|
|
20
26
|
var _fieldText = require("./field/fieldText.js");
|
|
21
27
|
var _FieldMessages = _interopRequireDefault(require("./field/FieldMessages.js"));
|
|
@@ -34,10 +40,36 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
34
40
|
var cache;
|
|
35
41
|
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
36
42
|
/** Same day and time (or both without a time). */const sameValue = (a, b) => (0, _calendarDate.isSameDay)(a.date, b.date) && (a.time?.hour ?? -1) === (b.time?.hour ?? -1) && (a.time?.minute ?? -1) === (b.time?.minute ?? -1);
|
|
43
|
+
const ALL_SYSTEMS = ['gregory', 'hijri', 'dual'];
|
|
44
|
+
const RTL = {
|
|
45
|
+
direction: 'rtl'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** The same kind of selection with nothing in it. */
|
|
49
|
+
const emptySelection = sel => sel.kind === 'single' ? {
|
|
50
|
+
kind: 'single',
|
|
51
|
+
day: null
|
|
52
|
+
} : sel.kind === 'range' ? {
|
|
53
|
+
kind: 'range',
|
|
54
|
+
from: null,
|
|
55
|
+
to: null
|
|
56
|
+
} : {
|
|
57
|
+
...sel,
|
|
58
|
+
days: []
|
|
59
|
+
};
|
|
37
60
|
|
|
38
61
|
/** Minute steps that divide the hour. */
|
|
39
62
|
const MINUTE_STEPS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60];
|
|
40
63
|
|
|
64
|
+
/** A folded calendar stays mounted, so it comes back on the month and view it showed. */
|
|
65
|
+
const FOLDED = {
|
|
66
|
+
display: 'none'
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** The later / earlier of a limit and a bound; the bound when there's no limit. */
|
|
70
|
+
const later = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) > 0 ? a : b;
|
|
71
|
+
const earlier = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) < 0 ? a : b;
|
|
72
|
+
|
|
41
73
|
/**
|
|
42
74
|
* A date & time picker: a value field that opens a sheet (or an inline panel)
|
|
43
75
|
* with a calendar and, for date-time values, a time row. Single, range and
|
|
@@ -77,6 +109,7 @@ const DateTimePicker = props => {
|
|
|
77
109
|
disabled = false,
|
|
78
110
|
readOnly = false,
|
|
79
111
|
allowTyping,
|
|
112
|
+
hideCalendarOnKeyboard = true,
|
|
80
113
|
allowFieldTyping,
|
|
81
114
|
allowClear,
|
|
82
115
|
errorMessage,
|
|
@@ -108,6 +141,11 @@ const DateTimePicker = props => {
|
|
|
108
141
|
initialVisibleDate,
|
|
109
142
|
enableMonthSwipe = true,
|
|
110
143
|
calendarSystem,
|
|
144
|
+
calendarSwitch,
|
|
145
|
+
onCalendarSystemChange,
|
|
146
|
+
dualDefaultTab = 'gregory',
|
|
147
|
+
hijriLocale = 'ar-SA',
|
|
148
|
+
renderCalendarSwitch,
|
|
111
149
|
showToday = false,
|
|
112
150
|
showHolidays = true,
|
|
113
151
|
onVisibleMonthChange,
|
|
@@ -115,6 +153,7 @@ const DateTimePicker = props => {
|
|
|
115
153
|
validate,
|
|
116
154
|
yearRange: yearRangeProp = _types.DEFAULT_YEAR_RANGE,
|
|
117
155
|
locale,
|
|
156
|
+
numerals: numeralsProp,
|
|
118
157
|
timeZone,
|
|
119
158
|
now,
|
|
120
159
|
timeFormat: timeFormatProp,
|
|
@@ -134,6 +173,7 @@ const DateTimePicker = props => {
|
|
|
134
173
|
theme,
|
|
135
174
|
styles,
|
|
136
175
|
strings: stringOverrides,
|
|
176
|
+
hijriStrings: hijriOverrides,
|
|
137
177
|
testID
|
|
138
178
|
} = props;
|
|
139
179
|
const tokens = (0, _react.useMemo)(() => (0, _tokens.buildTokens)(theme),
|
|
@@ -144,6 +184,69 @@ const DateTimePicker = props => {
|
|
|
144
184
|
const firstDayOfWeek = firstDayProp ?? (0, _locale.deriveFirstDayOfWeek)(loc);
|
|
145
185
|
// Month and year picks are for single dates only.
|
|
146
186
|
const precision = type === 'date' && mode === 'single' ? precisionProp : 'day';
|
|
187
|
+
// The calendars the switch offers: none for month and year picks (always
|
|
188
|
+
// Gregorian), or when the platform has no Hijri calendar.
|
|
189
|
+
const switchKey = Array.isArray(calendarSwitch) ? calendarSwitch.join(',') : String(!!calendarSwitch);
|
|
190
|
+
const switchSystems = (0, _react.useMemo)(() => {
|
|
191
|
+
if (!calendarSwitch || precision !== 'day' || !(0, _calendarSystem.isHijriSupported)()) return null;
|
|
192
|
+
const list = calendarSwitch === true ? ALL_SYSTEMS : ALL_SYSTEMS.filter(x => calendarSwitch.includes(x)).sort((a, b) => calendarSwitch.indexOf(a) - calendarSwitch.indexOf(b));
|
|
193
|
+
return list.length > 1 ? list : null;
|
|
194
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the list is compared by content
|
|
195
|
+
}, [switchKey, precision]);
|
|
196
|
+
const startSystem = () => {
|
|
197
|
+
const wanted = calendarSystem ?? 'gregory';
|
|
198
|
+
return switchSystems && !switchSystems.includes(wanted) ? switchSystems[0] ?? wanted : wanted;
|
|
199
|
+
};
|
|
200
|
+
// The switch changes this; a new calendarSystem prop starts over from it.
|
|
201
|
+
const [chosenSystem, setChosenSystem] = (0, _react.useState)(startSystem);
|
|
202
|
+
// The calendar the props open on, which a value from outside counts as
|
|
203
|
+
// picked in. The switch's own choice coming back as the calendarSystem prop
|
|
204
|
+
// (onCalendarSystemChange={setSystem}) isn't a new one.
|
|
205
|
+
const [openedOn, setOpenedOn] = (0, _react.useState)(startSystem);
|
|
206
|
+
const echo = (0, _react.useRef)(null);
|
|
207
|
+
(0, _react.useEffect)(() => {
|
|
208
|
+
const next = startSystem();
|
|
209
|
+
const own = echo.current === next;
|
|
210
|
+
echo.current = null;
|
|
211
|
+
if (own) return;
|
|
212
|
+
setChosenSystem(next);
|
|
213
|
+
setOpenedOn(next);
|
|
214
|
+
},
|
|
215
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- only when the props change
|
|
216
|
+
[calendarSystem, switchKey]);
|
|
217
|
+
// Month and year picks are Gregorian whatever the calendar system.
|
|
218
|
+
const system = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(chosenSystem) : 'gregory';
|
|
219
|
+
// A dual calendar shows one of its two tabs; each open starts on dualDefaultTab.
|
|
220
|
+
const [dualTab, setDualTab] = (0, _react.useState)(dualDefaultTab);
|
|
221
|
+
/** The calendar on screen. */
|
|
222
|
+
const shownSystem = system === 'dual' ? dualTab : system;
|
|
223
|
+
// A value from outside counts as picked in the calendar the props open on,
|
|
224
|
+
// not the one the user has since chosen in the switch.
|
|
225
|
+
const propSystem = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(openedOn) : 'gregory';
|
|
226
|
+
const outsideSystem = propSystem === 'dual' ? dualDefaultTab : propSystem;
|
|
227
|
+
// Picks say which calendar they were made in only when one can be Hijri.
|
|
228
|
+
const hijriInPlay = switchSystems !== null || system !== 'gregory';
|
|
229
|
+
/**
|
|
230
|
+
* The digits for one calendar: a Hijri calendar (and a date picked in it)
|
|
231
|
+
* shows Arabic digits (١٢٣) in any language; a Gregorian one shows 0–9.
|
|
232
|
+
* `numerals` sets both.
|
|
233
|
+
*/
|
|
234
|
+
const digitsFor = sys => {
|
|
235
|
+
const kind = numeralsProp ?? (sys === 'hijri' ? 'arabic' : 'latin');
|
|
236
|
+
if (kind === 'arabic') return _numerals.arabicDigits;
|
|
237
|
+
if (kind === 'latin') return _numerals.latinDigits;
|
|
238
|
+
return (0, _numerals.localeDigits)(sys === 'hijri' ? hijriLocale : loc);
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* The strings for one calendar. A Hijri one takes `hijriStrings` first, then
|
|
242
|
+
* AM / PM in `hijriLocale` (ص / م), then `strings`.
|
|
243
|
+
*/
|
|
244
|
+
const hijriStrings = (0, _react.useMemo)(() => ({
|
|
245
|
+
...strings,
|
|
246
|
+
...(0, _calendarSystem.hijriPeriods)(hijriLocale),
|
|
247
|
+
...(0, _defaultStrings.compactStrings)(hijriOverrides)
|
|
248
|
+
}), [strings, hijriLocale, hijriOverrides]);
|
|
249
|
+
const stringsFor = sys => sys === 'hijri' ? hijriStrings : strings;
|
|
147
250
|
const monthNames = (0, _react.useMemo)(() => (0, _localeNames.localeNames)(loc).monthsLong, [loc]);
|
|
148
251
|
/** A month or year pick shown as text: "March 2026" or "2026". */
|
|
149
252
|
const periodText = v => {
|
|
@@ -207,7 +310,7 @@ const DateTimePicker = props => {
|
|
|
207
310
|
const {
|
|
208
311
|
isOpen: sheetOpen,
|
|
209
312
|
open,
|
|
210
|
-
close
|
|
313
|
+
close: closePicker
|
|
211
314
|
} = (0, _useOpenPicker.useOpenPicker)({
|
|
212
315
|
disabled,
|
|
213
316
|
readOnly,
|
|
@@ -217,7 +320,7 @@ const DateTimePicker = props => {
|
|
|
217
320
|
onClose
|
|
218
321
|
});
|
|
219
322
|
const isOpen = isInline || sheetOpen;
|
|
220
|
-
const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen);
|
|
323
|
+
const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen && hideCalendarOnKeyboard);
|
|
221
324
|
// The picker's own boxes that have focus. Inline, another field on the
|
|
222
325
|
// screen can raise the keyboard, so the calendar folds only for these.
|
|
223
326
|
const [focusedParts, setFocusedParts] = (0, _react.useState)({});
|
|
@@ -264,16 +367,36 @@ const DateTimePicker = props => {
|
|
|
264
367
|
};
|
|
265
368
|
})).catch(() => requestedYears.current.delete(year));
|
|
266
369
|
}, [loadHolidays]);
|
|
370
|
+
// A month's grid also shows days of the months either side, and a Hijri
|
|
371
|
+
// month can run from December into January, so a month at either end of a
|
|
372
|
+
// year loads the year next to it too.
|
|
373
|
+
const loadHolidaysAround = (0, _react.useCallback)((year, month) => {
|
|
374
|
+
loadHolidaysFor(year);
|
|
375
|
+
if (month >= 11 && year < yearRange.last) loadHolidaysFor(year + 1);
|
|
376
|
+
if (month === 1 && year > yearRange.first) loadHolidaysFor(year - 1);
|
|
377
|
+
}, [loadHolidaysFor, yearRange.first, yearRange.last]);
|
|
267
378
|
const holidays = (0, _react.useMemo)(() => [...(holidaysProp ?? []), ...Object.values(loadedHolidays).flat()], [holidaysProp, loadedHolidays]);
|
|
268
379
|
|
|
269
380
|
// Limits are worked out when the picker opens (the screen's own validation
|
|
270
381
|
// after Confirm stays the final check).
|
|
271
382
|
const weekdaysKey = disabledWeekdays?.join(',');
|
|
383
|
+
// Limits built with `dependsOnNow` ("from now on") are rebuilt every minute
|
|
384
|
+
// while the picker is open.
|
|
385
|
+
const [minuteTick, setMinuteTick] = (0, _react.useState)(0);
|
|
272
386
|
const constraints = (0, _react.useMemo)(() => {
|
|
273
387
|
const nowDate = now?.() ?? new Date();
|
|
388
|
+
// yearRange bounds the limits too, so days outside it are greyed.
|
|
274
389
|
const limits = {
|
|
275
|
-
minDate,
|
|
276
|
-
|
|
390
|
+
minDate: later(minDate, {
|
|
391
|
+
year: yearRange.first,
|
|
392
|
+
month: 1,
|
|
393
|
+
day: 1
|
|
394
|
+
}),
|
|
395
|
+
maxDate: earlier(maxDate, {
|
|
396
|
+
year: yearRange.last,
|
|
397
|
+
month: 12,
|
|
398
|
+
day: 31
|
|
399
|
+
}),
|
|
277
400
|
disabledDates,
|
|
278
401
|
enabledDates,
|
|
279
402
|
timeBounds,
|
|
@@ -296,8 +419,8 @@ const DateTimePicker = props => {
|
|
|
296
419
|
type,
|
|
297
420
|
timeZone: zone,
|
|
298
421
|
now: nowDate,
|
|
299
|
-
minDate,
|
|
300
|
-
maxDate,
|
|
422
|
+
minDate: limits.minDate,
|
|
423
|
+
maxDate: limits.maxDate,
|
|
301
424
|
isDisabled: disabledDates,
|
|
302
425
|
isEnabled: enabledDates,
|
|
303
426
|
timeBounds,
|
|
@@ -305,8 +428,25 @@ const DateTimePicker = props => {
|
|
|
305
428
|
holidays,
|
|
306
429
|
disableHolidays
|
|
307
430
|
});
|
|
308
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- `isOpen` and `
|
|
309
|
-
}, [isOpen, today, type, zone, now, holidays, minDate, maxDate, disabledDates, enabledDates, timeBounds, weekdaysKey, disableHolidays, getConstraints]);
|
|
431
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- `isOpen`, `today` and `minuteTick` refresh the limits on open, at midnight and each minute; weekdays are compared by content
|
|
432
|
+
}, [isOpen, today, minuteTick, type, zone, now, holidays, minDate, maxDate, disabledDates, enabledDates, timeBounds, weekdaysKey, disableHolidays, getConstraints, yearRange]);
|
|
433
|
+
const followsClock = isOpen && constraints.dependsOnNow;
|
|
434
|
+
(0, _react.useEffect)(() => {
|
|
435
|
+
if (!followsClock) return;
|
|
436
|
+
let timer;
|
|
437
|
+
const arm = () => {
|
|
438
|
+
const ms = 60_000 - (now?.() ?? new Date()).getTime() % 60_000;
|
|
439
|
+
timer = setTimeout(() => {
|
|
440
|
+
setMinuteTick(n => n + 1);
|
|
441
|
+
arm();
|
|
442
|
+
}, ms);
|
|
443
|
+
// Under Node (e.g. Jest) the timer must not keep the process alive.
|
|
444
|
+
timer.unref?.();
|
|
445
|
+
};
|
|
446
|
+
arm();
|
|
447
|
+
return () => clearTimeout(timer);
|
|
448
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- armed while open with a clock-bound limit
|
|
449
|
+
}, [followsClock]);
|
|
310
450
|
|
|
311
451
|
// A typed field that doesn't parse blocks Confirm, per field: one end of a
|
|
312
452
|
// range can't hide the other end's problem.
|
|
@@ -333,14 +473,30 @@ const DateTimePicker = props => {
|
|
|
333
473
|
const [wheelSpinning, setWheelSpinning] = (0, _react.useState)(false);
|
|
334
474
|
// From/To layout: the end that calendar taps fill. perDate: the day the time row edits.
|
|
335
475
|
const [activeEnd, setActiveEnd] = (0, _react.useState)('from');
|
|
476
|
+
// From/To layout: a From or To field was tapped, so the next day tap edits that end only.
|
|
477
|
+
const [endPicked, setEndPicked] = (0, _react.useState)(false);
|
|
478
|
+
const activateEnd = (0, _react.useCallback)(end => {
|
|
479
|
+
setActiveEnd(end);
|
|
480
|
+
setEndPicked(true);
|
|
481
|
+
}, []);
|
|
336
482
|
const [activeDay, setActiveDay] = (0, _react.useState)(null);
|
|
337
483
|
const resetSelectionUi = (0, _react.useCallback)(() => {
|
|
484
|
+
// What was typed is gone with the selection, so nothing blocks Confirm.
|
|
485
|
+
setTypingBlocks({});
|
|
338
486
|
setPendingTimes({});
|
|
339
487
|
setActiveEnd('from');
|
|
488
|
+
setEndPicked(false);
|
|
340
489
|
setActiveDay(null);
|
|
341
490
|
}, []);
|
|
491
|
+
// A day in the month the calendar last showed, so a switch to the other
|
|
492
|
+
// calendar opens on the same days. Each open starts from the value again.
|
|
493
|
+
const shownAnchor = (0, _react.useRef)(null);
|
|
494
|
+
const rememberAnchor = (0, _react.useCallback)(day => {
|
|
495
|
+
shownAnchor.current = day;
|
|
496
|
+
}, []);
|
|
342
497
|
// Opening or closing starts fresh: nothing edited, nothing blocked.
|
|
343
498
|
(0, _react.useEffect)(() => {
|
|
499
|
+
shownAnchor.current = null;
|
|
344
500
|
edited.current = false;
|
|
345
501
|
setTypingBlocks({});
|
|
346
502
|
setTimeCheck(0);
|
|
@@ -404,6 +560,59 @@ const DateTimePicker = props => {
|
|
|
404
560
|
};
|
|
405
561
|
const valueKey = JSON.stringify(value ?? '');
|
|
406
562
|
|
|
563
|
+
// A selection belongs to the calendar it was picked in (Gregorian or Hijri):
|
|
564
|
+
// it shows only there, and the field writes it in that calendar. A saved
|
|
565
|
+
// value remembers its calendar; one from outside counts as picked in the
|
|
566
|
+
// calendar the picker opens on.
|
|
567
|
+
// The saved value as a draft, for the on-screen field and for comparing
|
|
568
|
+
// values by what they hold.
|
|
569
|
+
const saved = (0, _react.useMemo)(() => (0, _draft.createDraft)(mode, value, draftOptions),
|
|
570
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the value is compared by content (`valueKey`)
|
|
571
|
+
[valueKey, mode, draftOptions]);
|
|
572
|
+
/** A draft's days and times, so a value written another way ({to, from}) still matches. */
|
|
573
|
+
const contentOf = dr => JSON.stringify(valuesOf(dr));
|
|
574
|
+
const savedContent = contentOf(saved);
|
|
575
|
+
const savedSystemRef = (0, _react.useRef)(null);
|
|
576
|
+
const savedSystem = savedSystemRef.current?.content === savedContent ? savedSystemRef.current.system : outsideSystem;
|
|
577
|
+
const [draftSystem, setDraftSystem] = (0, _react.useState)(savedSystem);
|
|
578
|
+
// The draft is rebuilt on open and on a new value; so is its calendar. A new
|
|
579
|
+
// calendarSystem prop while the user is picking starts the selection over,
|
|
580
|
+
// since a selection is one calendar's.
|
|
581
|
+
const systemSeen = (0, _react.useRef)({
|
|
582
|
+
isOpen,
|
|
583
|
+
valueKey,
|
|
584
|
+
savedSystem
|
|
585
|
+
});
|
|
586
|
+
(0, _react.useEffect)(() => {
|
|
587
|
+
const seen = systemSeen.current;
|
|
588
|
+
systemSeen.current = {
|
|
589
|
+
isOpen,
|
|
590
|
+
valueKey,
|
|
591
|
+
savedSystem
|
|
592
|
+
};
|
|
593
|
+
setDraftSystem(savedSystem);
|
|
594
|
+
const systemOnly = seen.isOpen === isOpen && seen.valueKey === valueKey && seen.savedSystem !== savedSystem;
|
|
595
|
+
if (systemOnly && isOpen && edited.current) {
|
|
596
|
+
draft.clear();
|
|
597
|
+
resetSelectionUi();
|
|
598
|
+
}
|
|
599
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the draft's actions are stable
|
|
600
|
+
}, [isOpen, valueKey, savedSystem]);
|
|
601
|
+
(0, _react.useEffect)(() => setDualTab(dualDefaultTab), [isOpen, dualDefaultTab]);
|
|
602
|
+
const selectionShown = draftSystem === shownSystem;
|
|
603
|
+
/** Saves a value: with the calendar it was picked in, when one can be Hijri. */
|
|
604
|
+
const emitChange = (0, _react.useCallback)((wire, picked) => {
|
|
605
|
+
savedSystemRef.current = {
|
|
606
|
+
content: contentOf((0, _draft.createDraft)(mode, wire, draftOptions)),
|
|
607
|
+
system: picked
|
|
608
|
+
};
|
|
609
|
+
if (hijriInPlay) onChange(wire, {
|
|
610
|
+
calendarSystem: picked
|
|
611
|
+
});else onChange(wire);
|
|
612
|
+
},
|
|
613
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- contentOf reads only `type` and the options listed
|
|
614
|
+
[hijriInPlay, onChange, mode, draftOptions]);
|
|
615
|
+
|
|
407
616
|
/**
|
|
408
617
|
* Whether a draft can be saved as it stands: complete, every day allowed,
|
|
409
618
|
* every time allowed and on the minute step, and nothing being typed or
|
|
@@ -416,19 +625,19 @@ const DateTimePicker = props => {
|
|
|
416
625
|
|
|
417
626
|
// Every save: Confirm, an 'instant' edit (onConfirm is added by `confirm`).
|
|
418
627
|
const commit = (0, _react.useCallback)(wire => {
|
|
419
|
-
|
|
628
|
+
emitChange(wire, draftSystem);
|
|
420
629
|
onBlur?.();
|
|
421
|
-
}, [
|
|
630
|
+
}, [emitChange, draftSystem, onBlur]);
|
|
422
631
|
const confirm = (0, _react.useCallback)(() => {
|
|
423
632
|
if (!canConfirm) return;
|
|
424
633
|
const {
|
|
425
634
|
validate: check,
|
|
426
635
|
onError: report,
|
|
427
|
-
value:
|
|
636
|
+
value: current
|
|
428
637
|
} = latest.current;
|
|
429
638
|
if (timeBlocked) {
|
|
430
639
|
setTimeCheck(n => n + 1);
|
|
431
|
-
report?.(timeIssue ?? 'TIME_NOT_ALLOWED',
|
|
640
|
+
report?.(timeIssue ?? 'TIME_NOT_ALLOWED', current);
|
|
432
641
|
return;
|
|
433
642
|
}
|
|
434
643
|
const wire = (0, _draft.draftToWire)(preview, draftOptions);
|
|
@@ -444,14 +653,14 @@ const DateTimePicker = props => {
|
|
|
444
653
|
commit(wire);
|
|
445
654
|
onConfirm?.(wire);
|
|
446
655
|
edited.current = false;
|
|
447
|
-
if (!isInline)
|
|
448
|
-
}, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline,
|
|
656
|
+
if (!isInline) closePicker();
|
|
657
|
+
}, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline, closePicker]);
|
|
449
658
|
const clearValue = (0, _react.useCallback)(() => {
|
|
450
659
|
draft.clear();
|
|
451
660
|
resetSelectionUi();
|
|
452
661
|
edited.current = false;
|
|
453
|
-
|
|
454
|
-
}, [draft,
|
|
662
|
+
emitChange('', draftSystem);
|
|
663
|
+
}, [draft, emitChange, draftSystem, resetSelectionUi]);
|
|
455
664
|
const clearDraft = (0, _react.useCallback)(() => {
|
|
456
665
|
edited.current = true;
|
|
457
666
|
draft.clear();
|
|
@@ -460,9 +669,10 @@ const DateTimePicker = props => {
|
|
|
460
669
|
|
|
461
670
|
// × in the field above the calendar. 'instant' saves every edit, so it
|
|
462
671
|
// clears the saved value too (once; an empty value isn't saved again).
|
|
672
|
+
const hasSaved = valuesOf(saved).some(v => v !== null);
|
|
463
673
|
const clearInSheet = (0, _react.useCallback)(() => {
|
|
464
|
-
if (commitMode === 'instant' &&
|
|
465
|
-
}, [commitMode,
|
|
674
|
+
if (commitMode === 'instant' && hasSaved) clearValue();else clearDraft();
|
|
675
|
+
}, [commitMode, hasSaved, clearValue, clearDraft]);
|
|
466
676
|
|
|
467
677
|
// Opening or closing starts without the last `validate` message.
|
|
468
678
|
(0, _react.useEffect)(() => setValidation(null), [isOpen]);
|
|
@@ -473,15 +683,27 @@ const DateTimePicker = props => {
|
|
|
473
683
|
// An edit equal to the saved value isn't saved again; one `validate`
|
|
474
684
|
// rejected waits until the selection or the saved value changes.
|
|
475
685
|
const lastRejected = (0, _react.useRef)(null);
|
|
686
|
+
// The last value saved: not saved again while the parent's `value` catches
|
|
687
|
+
// up (a slow store, a server round trip) or when it never does.
|
|
688
|
+
const lastEmitted = (0, _react.useRef)(null);
|
|
476
689
|
(0, _react.useEffect)(() => {
|
|
477
690
|
lastRejected.current = null;
|
|
478
|
-
|
|
479
|
-
|
|
691
|
+
lastEmitted.current = null;
|
|
692
|
+
}, [valueKey, isOpen]);
|
|
693
|
+
// The field in the sheet saves once typing there is done (focus leaves it),
|
|
694
|
+
// so 09:30 isn't saved as 09:00 and 09:03 on the way.
|
|
695
|
+
const sheetTyping = !!(focusedParts.value || focusedParts['value-from'] || focusedParts['value-to']);
|
|
696
|
+
/** Saves the draft in instant mode; `typingDone` once the sheet's field is left. */
|
|
697
|
+
const saveInstant = typingDone => {
|
|
480
698
|
if (commitMode !== 'instant' || !isOpen || !edited.current) return;
|
|
481
|
-
if (timeIssue || !canSave(draft.draft)) return;
|
|
699
|
+
if (!typingDone || timeIssue || !canSave(draft.draft)) return;
|
|
482
700
|
const wire = draft.toWire();
|
|
483
701
|
const key = JSON.stringify(wire);
|
|
484
|
-
if (key ===
|
|
702
|
+
if (key === lastRejected.current || key === lastEmitted.current) return;
|
|
703
|
+
// The same dates picked in the same calendar aren't saved again; the same
|
|
704
|
+
// dates picked in the other calendar are.
|
|
705
|
+
const unchanged = key === valueKey || contentOf(draft.draft) === savedContent;
|
|
706
|
+
if (unchanged && draftSystem === savedSystem) return;
|
|
485
707
|
const message = latest.current.validate?.(wire);
|
|
486
708
|
if (message) {
|
|
487
709
|
lastRejected.current = key;
|
|
@@ -492,9 +714,22 @@ const DateTimePicker = props => {
|
|
|
492
714
|
latest.current.onError?.('VALIDATION', wire);
|
|
493
715
|
return;
|
|
494
716
|
}
|
|
717
|
+
lastEmitted.current = key;
|
|
495
718
|
commit(wire);
|
|
496
|
-
|
|
497
|
-
|
|
719
|
+
};
|
|
720
|
+
// Only typing waits for the field to be left; a tap is a finished edit.
|
|
721
|
+
const typedLast = (0, _react.useRef)(false);
|
|
722
|
+
(0, _react.useEffect)(() => saveInstant(!sheetTyping || !typedLast.current),
|
|
723
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- when the draft or what blocks it changes, not when callbacks are re-created
|
|
724
|
+
[commitMode, isOpen, sheetTyping, draft.draft, draftSystem, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
|
|
725
|
+
// Closing while the sheet's field still has focus ends the typing: an
|
|
726
|
+
// instant picker saves what was typed before it closes.
|
|
727
|
+
const saveInstantRef = (0, _react.useRef)(saveInstant);
|
|
728
|
+
saveInstantRef.current = saveInstant;
|
|
729
|
+
const close = (0, _react.useCallback)(() => {
|
|
730
|
+
saveInstantRef.current(true);
|
|
731
|
+
closePicker();
|
|
732
|
+
}, [closePicker]);
|
|
498
733
|
|
|
499
734
|
// A typed date with no time yet gets one the way a tapped day does: the fixed
|
|
500
735
|
// newDayTime, else a time already typed in the time row, else now.
|
|
@@ -502,14 +737,24 @@ const DateTimePicker = props => {
|
|
|
502
737
|
date: parsed.dateOnly,
|
|
503
738
|
time: fixedTime ?? pending[key] ?? nowTime()
|
|
504
739
|
} : null);
|
|
740
|
+
|
|
741
|
+
// Typed segments are Gregorian, so typing keeps the calendar a selection was
|
|
742
|
+
// picked in; into an empty draft, it takes the calendar on screen.
|
|
743
|
+
const adoptShownIfEmpty = () => {
|
|
744
|
+
if (valuesOf(d).every(v => v === null)) setDraftSystem(shownSystem);
|
|
745
|
+
};
|
|
505
746
|
const onSheetTyped = parsed => {
|
|
506
747
|
edited.current = true;
|
|
748
|
+
typedLast.current = true;
|
|
749
|
+
adoptShownIfEmpty();
|
|
507
750
|
const typed = withFilledTime(parsed, 'single');
|
|
508
751
|
setTypingBlock('single', !parsed.isEmpty && !typed);
|
|
509
752
|
if (typed) draft.setValue(typed, 'single');else if (parsed.isEmpty) draft.clear();
|
|
510
753
|
};
|
|
511
754
|
const onRangeTyped = (end, parsed) => {
|
|
512
755
|
edited.current = true;
|
|
756
|
+
typedLast.current = true;
|
|
757
|
+
adoptShownIfEmpty();
|
|
513
758
|
const typed = withFilledTime(parsed, end);
|
|
514
759
|
setTypingBlock(end, !parsed.isEmpty && !typed);
|
|
515
760
|
if (typed || parsed.isEmpty) draft.setValue(typed, end);
|
|
@@ -530,28 +775,77 @@ const DateTimePicker = props => {
|
|
|
530
775
|
minute: capped % 60
|
|
531
776
|
};
|
|
532
777
|
}, [now, zone, minuteStep]);
|
|
778
|
+
|
|
779
|
+
// A range end picked on the start's day starts an hour after the start (at
|
|
780
|
+
// most the day's latest allowed time, or its last step), so the range isn't
|
|
781
|
+
// out of order before the user has touched the time.
|
|
782
|
+
// A time typed for the end before its day is kept as typed.
|
|
783
|
+
const endTimeFor = (from, day, typed) => {
|
|
784
|
+
if (!fixedTime && typed) return typed;
|
|
785
|
+
const time = fixedTime ?? nowTime();
|
|
786
|
+
if (!from?.time || !(0, _calendarDate.isSameDay)(from.date, day)) return time;
|
|
787
|
+
const start = from.time.hour * 60 + from.time.minute;
|
|
788
|
+
if (time.hour * 60 + time.minute > start) return time;
|
|
789
|
+
// Within the day's allowed hours when it has them.
|
|
790
|
+
const max = constraints.timeBounds(day)?.max;
|
|
791
|
+
const last = max ? max.hour * 60 + max.minute : 24 * 60 - Math.max(1, minuteStep);
|
|
792
|
+
const end = Math.min(start + 60, last);
|
|
793
|
+
return {
|
|
794
|
+
hour: Math.floor(end / 60),
|
|
795
|
+
minute: end % 60
|
|
796
|
+
};
|
|
797
|
+
};
|
|
533
798
|
const onSelectDay = (0, _react.useCallback)(day => {
|
|
534
799
|
edited.current = true;
|
|
535
|
-
|
|
800
|
+
typedLast.current = false;
|
|
801
|
+
// A pick in the other calendar starts over: the selection is one calendar's.
|
|
802
|
+
const fresh = draftSystem !== shownSystem && valuesOf(d).some(v => v !== null);
|
|
803
|
+
setDraftSystem(shownSystem);
|
|
804
|
+
const cur = fresh ? (0, _draft.clearDraft)(d) : d;
|
|
805
|
+
const end0 = fresh ? 'from' : activeEnd;
|
|
806
|
+
const dayInEdit = fresh ? null : activeDay;
|
|
807
|
+
const times = fresh ? {} : pending;
|
|
808
|
+
if (fresh) {
|
|
809
|
+
draft.clear();
|
|
810
|
+
resetSelectionUi();
|
|
811
|
+
}
|
|
812
|
+
if (cur.mode === 'range') {
|
|
536
813
|
if (rangeLayout === 'fromTo') {
|
|
814
|
+
setEndPicked(false);
|
|
815
|
+
// A full range: the tap starts a new one (or moves the nearest end).
|
|
816
|
+
if (!endPicked && cur.from.value && cur.to.value) {
|
|
817
|
+
const moveNearest = range?.reselect === 'moveNearestEnd';
|
|
818
|
+
const nearest = Math.abs((0, _calendarDate.daysBetween)(cur.from.value.date, day)) < Math.abs((0, _calendarDate.daysBetween)(cur.to.value.date, day)) ? 'from' : 'to';
|
|
819
|
+
const end = moveNearest ? nearest : 'from';
|
|
820
|
+
setTypingBlock('from', false);
|
|
821
|
+
setTypingBlock('to', false);
|
|
822
|
+
draft.selectDay(day, fixedTime ?? times[end] ?? nowTime());
|
|
823
|
+
setActiveEnd(moveNearest ? nearest : 'to');
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
// Choosing the end after a start tap: a day before the start moves the start.
|
|
827
|
+
const end1 = end0 === 'to' && !endPicked && cur.from.value && (0, _calendarDate.compareCalendarDates)(day, cur.from.value.date) < 0 ? 'from' : end0;
|
|
537
828
|
// The tapped day replaces whatever was typed in this end only.
|
|
538
|
-
setTypingBlock(
|
|
539
|
-
draft.setRangeEnd(day,
|
|
540
|
-
|
|
829
|
+
setTypingBlock(end1, false);
|
|
830
|
+
draft.setRangeEnd(day, end1, end1 === 'to' ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times.from ?? nowTime());
|
|
831
|
+
// The start tapped again where a range can't be one day deselects
|
|
832
|
+
// it, so the next tap picks the start again.
|
|
833
|
+
const deselects = end1 === 'to' && !(0, _draft.sameDayRangeOk)(draftOptions) && (0, _calendarDate.isSameDay)(cur.from.value?.date, day);
|
|
834
|
+
if (end0 === 'from') setActiveEnd('to');else if (deselects) setActiveEnd('from');
|
|
541
835
|
return;
|
|
542
836
|
}
|
|
543
837
|
// The single field: the first tap is the start, the next one the end.
|
|
544
|
-
const startsOver = !
|
|
838
|
+
const startsOver = !cur.from.value || !!cur.to.value && range?.reselect !== 'moveNearestEnd';
|
|
545
839
|
const end = startsOver ? 'from' : 'to';
|
|
546
840
|
setTypingBlock('single', false);
|
|
547
|
-
draft.selectDay(day, fixedTime ??
|
|
841
|
+
draft.selectDay(day, end === 'to' && !cur.to.value ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times[end] ?? nowTime());
|
|
548
842
|
return;
|
|
549
843
|
}
|
|
550
|
-
if (
|
|
844
|
+
if (cur.mode === 'multiple') {
|
|
551
845
|
const perDate = type === 'datetime' && multipleTimeMode === 'perDate';
|
|
552
|
-
const picked =
|
|
846
|
+
const picked = cur.slots.some(slot => (0, _calendarDate.isSameDay)(slot.value?.date, day));
|
|
553
847
|
// perDate: a tap on a picked day first makes it the one the time row edits.
|
|
554
|
-
if (perDate && picked && !(0, _calendarDate.isSameDay)(
|
|
848
|
+
if (perDate && picked && !(0, _calendarDate.isSameDay)(dayInEdit, day)) {
|
|
555
849
|
setActiveDay(day);
|
|
556
850
|
return;
|
|
557
851
|
}
|
|
@@ -560,18 +854,28 @@ const DateTimePicker = props => {
|
|
|
560
854
|
return;
|
|
561
855
|
}
|
|
562
856
|
setTypingBlock('single', false);
|
|
563
|
-
draft.selectDay(day, fixedTime ??
|
|
564
|
-
},
|
|
857
|
+
draft.selectDay(day, fixedTime ?? times.single ?? nowTime());
|
|
858
|
+
},
|
|
859
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- valuesOf reads only `d` and props listed here
|
|
860
|
+
[d, draft, nowTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock, draftSystem, shownSystem, resetSelectionUi, endPicked, draftOptions, minuteStep, constraints]);
|
|
861
|
+
|
|
862
|
+
// The calendar gets a tap handler that never changes, so its memoized day
|
|
863
|
+
// cells don't all redraw on every tap; it calls the current one.
|
|
864
|
+
const selectDayRef = (0, _react.useRef)(onSelectDay);
|
|
865
|
+
selectDayRef.current = onSelectDay;
|
|
866
|
+
const onSelectDayStable = (0, _react.useCallback)(day => selectDayRef.current(day), []);
|
|
565
867
|
|
|
566
868
|
// Greying that depends on what's picked: range length, From/To order, the multiple cap.
|
|
567
869
|
const calendarConstraints = (0, _react.useMemo)(() => {
|
|
568
870
|
if (d.mode === 'range') {
|
|
569
|
-
|
|
871
|
+
// A full From/To range greys nothing: the next tap starts a new one.
|
|
872
|
+
const choosingEnd = rangeLayout === 'fromTo' ? activeEnd === 'to' && (endPicked || !d.to.value) : !!d.from.value && !d.to.value;
|
|
570
873
|
return (0, _selectionRules.withSelectionRules)(constraints, {
|
|
571
874
|
rangeStart: choosingEnd ? d.from.value?.date : null,
|
|
572
875
|
minDays: range?.minDays,
|
|
573
876
|
maxDays: range?.maxDays,
|
|
574
|
-
|
|
877
|
+
// Only an end chosen from the To field can't go before the start.
|
|
878
|
+
blockBeforeStart: rangeLayout === 'fromTo' && endPicked
|
|
575
879
|
});
|
|
576
880
|
}
|
|
577
881
|
if (d.mode === 'multiple') {
|
|
@@ -582,7 +886,7 @@ const DateTimePicker = props => {
|
|
|
582
886
|
});
|
|
583
887
|
}
|
|
584
888
|
return constraints;
|
|
585
|
-
}, [constraints, d, rangeLayout, activeEnd, range?.minDays, range?.maxDays, multiple?.maxSelections]);
|
|
889
|
+
}, [constraints, d, rangeLayout, activeEnd, endPicked, range?.minDays, range?.maxDays, multiple?.maxSelections]);
|
|
586
890
|
const selection = draft.draft.mode === 'single' ? {
|
|
587
891
|
kind: 'single',
|
|
588
892
|
day: draft.draft.slot.value?.date ?? null
|
|
@@ -609,13 +913,13 @@ const DateTimePicker = props => {
|
|
|
609
913
|
}
|
|
610
914
|
}, [isOpen, constraints, today]);
|
|
611
915
|
const handleVisibleMonth = (0, _react.useCallback)((year, month) => {
|
|
612
|
-
|
|
916
|
+
loadHolidaysAround(year, month);
|
|
613
917
|
onVisibleMonthChange?.(year, month);
|
|
614
|
-
}, [
|
|
918
|
+
}, [loadHolidaysAround, onVisibleMonthChange]);
|
|
615
919
|
(0, _react.useEffect)(() => {
|
|
616
920
|
if (!isOpen) return;
|
|
617
|
-
const anchor = selection.kind === 'single' ? selection.day : null;
|
|
618
|
-
|
|
921
|
+
const anchor = (selection.kind === 'single' ? selection.day : null) ?? today;
|
|
922
|
+
loadHolidaysAround(anchor.year, anchor.month);
|
|
619
923
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- once per open
|
|
620
924
|
}, [isOpen]);
|
|
621
925
|
|
|
@@ -666,17 +970,24 @@ const DateTimePicker = props => {
|
|
|
666
970
|
return;
|
|
667
971
|
}
|
|
668
972
|
setTriggerError('');
|
|
669
|
-
|
|
973
|
+
// Typing keeps the calendar the saved value was picked in.
|
|
974
|
+
emitChange(wire, savedSystem);
|
|
670
975
|
onBlur?.();
|
|
671
976
|
};
|
|
672
977
|
|
|
978
|
+
/** A value's date in the calendar it was picked in: Hijri text, or none for the dateFormat. */
|
|
979
|
+
const dateTextFor = picked => picked === 'hijri' ? v => (0, _calendarSystem.hijriDateText)(v.date, hijriLocale) ?? (0, _fieldText.formatDateText)(v, dateFormat) : undefined;
|
|
980
|
+
const savedDateText = dateTextFor(savedSystem);
|
|
981
|
+
const draftDateText = dateTextFor(draftSystem);
|
|
982
|
+
const savedStrings = stringsFor(savedSystem);
|
|
983
|
+
const draftStrings = stringsFor(draftSystem);
|
|
984
|
+
// Error messages inside the picker follow the tab on screen; the on-screen
|
|
985
|
+
// field's keep `strings`.
|
|
986
|
+
const shownStrings = stringsFor(shownSystem);
|
|
987
|
+
|
|
673
988
|
// What the on-screen field shows: the saved value, never the draft.
|
|
674
|
-
const savedKey = valueKey;
|
|
675
|
-
const saved = (0, _react.useMemo)(() => (0, _draft.createDraft)(mode, value, draftOptions),
|
|
676
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- the value is compared by content (`savedKey`)
|
|
677
|
-
[savedKey, mode, draftOptions]);
|
|
678
989
|
const savedSingle = saved.mode === 'single' ? saved.slot.value : null;
|
|
679
|
-
const savedText = saved.mode === 'range' ? (0, _fieldText.formatRangeText)(saved.from.value, saved.to.value, type, dateFormat, timeFormat, strings.rangeSeparator) : saved.mode === 'multiple' ? (0, _fieldText.formatMultipleText)(saved.slots.map(slot => slot.value), type, dateFormat, timeFormat) : precision !== 'day' ? periodText(savedSingle) : undefined;
|
|
990
|
+
const savedText = saved.mode === 'range' ? (0, _fieldText.formatRangeText)(saved.from.value, saved.to.value, type, dateFormat, timeFormat, strings.rangeSeparator, savedDateText, savedStrings) : saved.mode === 'multiple' ? (0, _fieldText.formatMultipleText)(saved.slots.map(slot => slot.value), type, dateFormat, timeFormat, savedDateText, savedStrings) : precision !== 'day' ? periodText(savedSingle) : undefined;
|
|
680
991
|
const periodPlaceholder = precision === 'year' ? strings.placeholderYear : precision === 'month' ? `${strings.placeholderMonth} ${strings.placeholderYear}` : undefined;
|
|
681
992
|
|
|
682
993
|
// The time a custom renderTimeRow edits, and how it sets it (the same
|
|
@@ -702,7 +1013,7 @@ const DateTimePicker = props => {
|
|
|
702
1013
|
type,
|
|
703
1014
|
mode,
|
|
704
1015
|
value,
|
|
705
|
-
displayText: savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat),
|
|
1016
|
+
displayText: digitsFor(savedSystem)(savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat, savedDateText, savedStrings)),
|
|
706
1017
|
disabled,
|
|
707
1018
|
readOnly,
|
|
708
1019
|
isOpen,
|
|
@@ -723,11 +1034,11 @@ const DateTimePicker = props => {
|
|
|
723
1034
|
};
|
|
724
1035
|
const sheetValue = draft.draft.mode === 'single' ? draft.draft.slot.value : null;
|
|
725
1036
|
// A time outside the limits is explained under the time row, not here.
|
|
726
|
-
const sheetValueError = sheetValue && dayOff(sheetValue.date) ?
|
|
1037
|
+
const sheetValueError = sheetValue && dayOff(sheetValue.date) ? shownStrings.errorNotAllowed : '';
|
|
727
1038
|
let rangeError = '';
|
|
728
1039
|
if (d.mode === 'range' && d.from.value && d.to.value) {
|
|
729
1040
|
const length = (0, _calendarDate.daysBetween)(d.from.value.date, d.to.value.date) + 1;
|
|
730
|
-
if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError =
|
|
1041
|
+
if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError = shownStrings.errorNotAllowed;else if (previewIssue === 'RANGE_ORDER') rangeError = shownStrings.errorRangeOrder;else if (previewIssue === 'RANGE_LENGTH') rangeError = range?.minDays !== undefined && length < range.minDays ? shownStrings.errorRangeTooShort(range.minDays) : shownStrings.errorRangeTooLong(range?.maxDays ?? length);
|
|
731
1042
|
}
|
|
732
1043
|
const fieldCommon = {
|
|
733
1044
|
type,
|
|
@@ -743,8 +1054,11 @@ const DateTimePicker = props => {
|
|
|
743
1054
|
};
|
|
744
1055
|
const trigger = !showField || isInline ? null : renderField ? renderField(state) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
|
|
745
1056
|
...fieldCommon,
|
|
1057
|
+
strings: savedStrings,
|
|
1058
|
+
errorStrings: strings,
|
|
746
1059
|
value: savedSingle,
|
|
747
1060
|
displayText: savedText,
|
|
1061
|
+
dateText: savedDateText,
|
|
748
1062
|
allowTyping: mode === 'single' && precision === 'day' && allowFieldTyping,
|
|
749
1063
|
onTypingDone: onTriggerTyped,
|
|
750
1064
|
onTyped: () => setTriggerError(''),
|
|
@@ -774,8 +1088,11 @@ const DateTimePicker = props => {
|
|
|
774
1088
|
testID: testID ? `${testID}-value` : undefined
|
|
775
1089
|
}) : mode === 'single' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
|
|
776
1090
|
...fieldCommon,
|
|
1091
|
+
strings: draftStrings,
|
|
1092
|
+
errorStrings: shownStrings,
|
|
777
1093
|
value: sheetValue,
|
|
778
1094
|
displayText: precision !== 'day' ? periodText(sheetValue) : undefined,
|
|
1095
|
+
dateText: draftDateText,
|
|
779
1096
|
placeholder: sheetOptions?.fieldPlaceholder ?? periodPlaceholder,
|
|
780
1097
|
allowTyping: allowTyping && precision === 'day',
|
|
781
1098
|
onTyped: onSheetTyped,
|
|
@@ -788,13 +1105,16 @@ const DateTimePicker = props => {
|
|
|
788
1105
|
testID: testID ? `${testID}-value` : undefined
|
|
789
1106
|
}) : d.mode === 'range' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_RangeFields.default, {
|
|
790
1107
|
...fieldCommon,
|
|
1108
|
+
strings: draftStrings,
|
|
1109
|
+
errorStrings: shownStrings,
|
|
791
1110
|
layout: rangeLayout,
|
|
1111
|
+
dateText: draftDateText,
|
|
792
1112
|
showIcon: sheetOptions?.fieldIcon,
|
|
793
1113
|
from: d.from.value,
|
|
794
1114
|
to: d.to.value,
|
|
795
1115
|
placeholder: sheetOptions?.fieldPlaceholder,
|
|
796
1116
|
activeEnd: activeEnd,
|
|
797
|
-
onActivate:
|
|
1117
|
+
onActivate: activateEnd,
|
|
798
1118
|
allowTyping: allowTyping,
|
|
799
1119
|
onTyped: onRangeTyped,
|
|
800
1120
|
onFocusChange: (end, f) => reportFocus(`value-${end}`, f),
|
|
@@ -805,8 +1125,9 @@ const DateTimePicker = props => {
|
|
|
805
1125
|
testID: testID
|
|
806
1126
|
}) : d.mode === 'multiple' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
|
|
807
1127
|
...fieldCommon,
|
|
1128
|
+
strings: draftStrings,
|
|
808
1129
|
value: null,
|
|
809
|
-
displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat),
|
|
1130
|
+
displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat, draftDateText, draftStrings),
|
|
810
1131
|
placeholder: sheetOptions?.fieldPlaceholder,
|
|
811
1132
|
allowClear: allowClear,
|
|
812
1133
|
onClear: clearInSheet,
|
|
@@ -815,37 +1136,102 @@ const DateTimePicker = props => {
|
|
|
815
1136
|
active: true,
|
|
816
1137
|
testID: testID ? `${testID}-value` : undefined
|
|
817
1138
|
}) : null;
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1139
|
+
const systemLabels = {
|
|
1140
|
+
gregory: strings.calendarGregorian ?? _defaultStrings.DEFAULT_STRINGS.calendarGregorian,
|
|
1141
|
+
hijri: strings.calendarHijri ?? _defaultStrings.DEFAULT_STRINGS.calendarHijri,
|
|
1142
|
+
dual: strings.calendarDual ?? _defaultStrings.DEFAULT_STRINGS.calendarDual
|
|
1143
|
+
};
|
|
1144
|
+
const systemA11yLabel = strings.a11yCalendarSystem ?? _defaultStrings.DEFAULT_STRINGS.a11yCalendarSystem;
|
|
1145
|
+
const chooseSystem = next => {
|
|
1146
|
+
if (next === system) return;
|
|
1147
|
+
setChosenSystem(next);
|
|
1148
|
+
if (next === 'dual') setDualTab(dualDefaultTab);
|
|
1149
|
+
echo.current = next;
|
|
1150
|
+
onCalendarSystemChange?.(next);
|
|
1151
|
+
};
|
|
1152
|
+
const calendarSwitchNode = !switchSystems ? null : renderCalendarSwitch ? renderCalendarSwitch({
|
|
1153
|
+
systems: switchSystems,
|
|
1154
|
+
selected: system,
|
|
1155
|
+
onSelect: chooseSystem,
|
|
1156
|
+
tokens,
|
|
1157
|
+
strings
|
|
1158
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
|
|
1159
|
+
variant: "switch",
|
|
1160
|
+
options: switchSystems.map(v => {
|
|
1161
|
+
return {
|
|
1162
|
+
value: v,
|
|
1163
|
+
label: systemLabels[v]
|
|
1164
|
+
};
|
|
1165
|
+
}),
|
|
1166
|
+
selected: system,
|
|
1167
|
+
onSelect: chooseSystem,
|
|
1168
|
+
accessibilityLabel: systemA11yLabel,
|
|
845
1169
|
tokens: tokens,
|
|
846
1170
|
styles: styles,
|
|
847
|
-
|
|
848
|
-
|
|
1171
|
+
testID: testID ? `${testID}-calendar-switch` : undefined
|
|
1172
|
+
});
|
|
1173
|
+
const dualTabs = system !== 'dual' ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
|
|
1174
|
+
variant: "tabs",
|
|
1175
|
+
options: [{
|
|
1176
|
+
value: 'gregory',
|
|
1177
|
+
label: systemLabels.gregory
|
|
1178
|
+
}, {
|
|
1179
|
+
value: 'hijri',
|
|
1180
|
+
label: systemLabels.hijri
|
|
1181
|
+
}],
|
|
1182
|
+
selected: dualTab,
|
|
1183
|
+
onSelect: setDualTab,
|
|
1184
|
+
accessibilityLabel: systemA11yLabel,
|
|
1185
|
+
tokens: tokens,
|
|
1186
|
+
styles: styles,
|
|
1187
|
+
testID: testID ? `${testID}-dual-tabs` : undefined
|
|
1188
|
+
});
|
|
1189
|
+
// The Hijri tab lays out its calendar and time rows right to left; the
|
|
1190
|
+
// wrapper always renders, so a tab change doesn't remount the time boxes.
|
|
1191
|
+
const hijriShown = shownSystem === 'hijri';
|
|
1192
|
+
const mirrored = node => node == null ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_direction.RtlContext.Provider, {
|
|
1193
|
+
value: hijriShown || null,
|
|
1194
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1195
|
+
style: hijriShown ? RTL : undefined,
|
|
1196
|
+
children: node
|
|
1197
|
+
})
|
|
1198
|
+
});
|
|
1199
|
+
// Another calendar opens on the days the last one showed, else on the
|
|
1200
|
+
// selection (shown or not), else where the picker would open.
|
|
1201
|
+
const calendarAnchor = shownAnchor.current ?? (selectionShown ? null : (0, _selection.firstSelectedDay)(selection)) ?? initialVisibleDate;
|
|
1202
|
+
const calendar = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1203
|
+
style: folded ? FOLDED : undefined,
|
|
1204
|
+
children: [calendarSwitchNode, dualTabs, mirrored(/*#__PURE__*/(0, _jsxRuntime.jsx)(_Calendar.default, {
|
|
1205
|
+
constraints: selectionShown ? calendarConstraints : constraints,
|
|
1206
|
+
today: today,
|
|
1207
|
+
initialVisibleDate: calendarAnchor,
|
|
1208
|
+
selection: selectionShown ? selection : emptySelection(selection),
|
|
1209
|
+
onSelectDay: onSelectDayStable,
|
|
1210
|
+
firstDayOfWeek: firstDayOfWeek,
|
|
1211
|
+
showOutsideDays: showOutsideDays,
|
|
1212
|
+
showHolidays: showHolidays,
|
|
1213
|
+
yearRange: yearRange,
|
|
1214
|
+
locale: shownSystem === 'hijri' ? hijriLocale : loc,
|
|
1215
|
+
calendarSystem: shownSystem,
|
|
1216
|
+
initialView: initialView,
|
|
1217
|
+
precision: precision,
|
|
1218
|
+
enableMonthSwipe: enableMonthSwipe,
|
|
1219
|
+
showToday: showToday,
|
|
1220
|
+
onVisibleMonthChange: handleVisibleMonth,
|
|
1221
|
+
onAnchorChange: rememberAnchor,
|
|
1222
|
+
renderDay: renderDay,
|
|
1223
|
+
renderWeekday: renderWeekday,
|
|
1224
|
+
renderMonthChip: renderMonthChip,
|
|
1225
|
+
renderYearCell: renderYearCell,
|
|
1226
|
+
renderMonthCell: renderMonthCell,
|
|
1227
|
+
renderEmptyState: renderEmptyState,
|
|
1228
|
+
icons: icons,
|
|
1229
|
+
iconProps: iconProps,
|
|
1230
|
+
tokens: tokens,
|
|
1231
|
+
styles: styles,
|
|
1232
|
+
strings: stringsFor(shownSystem),
|
|
1233
|
+
testID: testID
|
|
1234
|
+
}, shownSystem))]
|
|
849
1235
|
});
|
|
850
1236
|
const timeRow = type !== 'datetime' ? null : renderTimeRow ? renderTimeRow(state) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_TimeRows.default, {
|
|
851
1237
|
draft: d,
|
|
@@ -872,14 +1258,26 @@ const DateTimePicker = props => {
|
|
|
872
1258
|
onPendingChange: onRowPending,
|
|
873
1259
|
tokens: tokens,
|
|
874
1260
|
styles: styles,
|
|
875
|
-
strings:
|
|
1261
|
+
strings: stringsFor(shownSystem),
|
|
876
1262
|
testID: testID
|
|
877
1263
|
});
|
|
878
1264
|
|
|
879
1265
|
// Shown while the selection is still the one it was given for.
|
|
880
1266
|
const validationMessage = validation && (validation.key === JSON.stringify(draft.toWire()) || validation.key === JSON.stringify((0, _draft.draftToWire)(preview, draftOptions))) ? validation.message : null;
|
|
1267
|
+
|
|
1268
|
+
// The field writes the date in the digits of the calendar it was picked in;
|
|
1269
|
+
// the calendar and the time rows follow the tab that shows.
|
|
881
1270
|
const sheetContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
882
|
-
children: [
|
|
1271
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1272
|
+
value: digitsFor(draftSystem),
|
|
1273
|
+
children: sheetField
|
|
1274
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1275
|
+
value: digitsFor(shownSystem),
|
|
1276
|
+
children: calendar
|
|
1277
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1278
|
+
value: digitsFor(shownSystem),
|
|
1279
|
+
children: mirrored(timeRow)
|
|
1280
|
+
}), validationMessage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_FieldMessages.default, {
|
|
883
1281
|
error: validationMessage,
|
|
884
1282
|
tokens: tokens,
|
|
885
1283
|
styles: {
|
|
@@ -889,7 +1287,8 @@ const DateTimePicker = props => {
|
|
|
889
1287
|
testID: testID ? `${testID}-validation` : undefined
|
|
890
1288
|
}) : null]
|
|
891
1289
|
});
|
|
892
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(
|
|
1290
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_numerals2.NumeralsContext.Provider, {
|
|
1291
|
+
value: digitsFor(savedSystem),
|
|
893
1292
|
children: [trigger, /*#__PURE__*/(0, _jsxRuntime.jsx)(_PickerContainer.default, {
|
|
894
1293
|
presentation: presentation,
|
|
895
1294
|
isOpen: isOpen,
|