rn-grid-date-time-picker 1.0.0 → 1.1.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 +61 -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 +444 -82
- 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 +43 -5
- 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 +9 -1
- 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 +1 -1
- 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 +3 -1
- package/lib/commonjs/components/field/RangeFields.js.map +1 -1
- package/lib/commonjs/components/field/SegmentedInput.js +7 -2
- package/lib/commonjs/components/field/SegmentedInput.js.map +1 -1
- package/lib/commonjs/components/field/ValueField.js +8 -4
- package/lib/commonjs/components/field/ValueField.js.map +1 -1
- package/lib/commonjs/components/field/fieldText.js +19 -12
- 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 +7 -1
- package/lib/commonjs/components/theme/defaultStrings.js.map +1 -1
- 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 +4 -1
- 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/types.js +10 -0
- package/lib/commonjs/components/types.js.map +1 -1
- package/lib/commonjs/core/calendarSystem.js +85 -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 +14 -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 +450 -88
- 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 +43 -5
- 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 +9 -1
- 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 +1 -1
- 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 +3 -1
- package/lib/module/components/field/RangeFields.js.map +1 -1
- package/lib/module/components/field/SegmentedInput.js +7 -2
- package/lib/module/components/field/SegmentedInput.js.map +1 -1
- package/lib/module/components/field/ValueField.js +8 -4
- package/lib/module/components/field/ValueField.js.map +1 -1
- package/lib/module/components/field/fieldText.js +20 -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 +7 -1
- package/lib/module/components/theme/defaultStrings.js.map +1 -1
- 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 +4 -1
- 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/types.js +10 -0
- package/lib/module/components/types.js.map +1 -1
- package/lib/module/core/calendarSystem.js +81 -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/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 +3 -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 +3 -0
- package/lib/typescript/commonjs/src/components/field/ValueField.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/field/fieldText.d.ts +9 -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 +11 -2
- package/lib/typescript/commonjs/src/components/theme/defaultStrings.d.ts.map +1 -1
- 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/types.d.ts +77 -4
- package/lib/typescript/commonjs/src/components/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/calendarSystem.d.ts +10 -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/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 +3 -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 +3 -0
- package/lib/typescript/module/src/components/field/ValueField.d.ts.map +1 -1
- package/lib/typescript/module/src/components/field/fieldText.d.ts +9 -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 +11 -2
- package/lib/typescript/module/src/components/theme/defaultStrings.d.ts.map +1 -1
- 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/types.d.ts +77 -4
- package/lib/typescript/module/src/components/types.d.ts.map +1 -1
- package/lib/typescript/module/src/core/calendarSystem.d.ts +10 -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 +556 -102
- package/src/components/calendar/Calendar.tsx +54 -16
- package/src/components/calendar/CalendarHeader.tsx +38 -7
- package/src/components/calendar/CalendarSwitch.tsx +170 -0
- package/src/components/calendar/DayCell.tsx +16 -4
- package/src/components/calendar/DayGrid.tsx +13 -1
- package/src/components/calendar/PeriodGrid.tsx +3 -1
- package/src/components/calendar/calendarStyles.ts +1 -1
- 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 +8 -2
- package/src/components/field/SegmentedInput.tsx +7 -2
- package/src/components/field/ValueField.tsx +12 -4
- package/src/components/field/fieldText.ts +45 -13
- 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 +18 -3
- package/src/components/theme/numerals.ts +11 -0
- package/src/components/theme/styleKeys.ts +13 -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/types.ts +79 -4
- package/src/core/calendarSystem.ts +103 -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,21 @@ 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 _numerals2 = require("./theme/numerals.js");
|
|
23
|
+
var _selection = require("./calendar/selection.js");
|
|
19
24
|
var _PickerContainer = _interopRequireDefault(require("./container/PickerContainer.js"));
|
|
20
25
|
var _fieldText = require("./field/fieldText.js");
|
|
21
26
|
var _FieldMessages = _interopRequireDefault(require("./field/FieldMessages.js"));
|
|
@@ -34,10 +39,33 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
34
39
|
var cache;
|
|
35
40
|
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
41
|
/** 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);
|
|
42
|
+
const ALL_SYSTEMS = ['gregory', 'hijri', 'dual'];
|
|
43
|
+
|
|
44
|
+
/** The same kind of selection with nothing in it. */
|
|
45
|
+
const emptySelection = sel => sel.kind === 'single' ? {
|
|
46
|
+
kind: 'single',
|
|
47
|
+
day: null
|
|
48
|
+
} : sel.kind === 'range' ? {
|
|
49
|
+
kind: 'range',
|
|
50
|
+
from: null,
|
|
51
|
+
to: null
|
|
52
|
+
} : {
|
|
53
|
+
...sel,
|
|
54
|
+
days: []
|
|
55
|
+
};
|
|
37
56
|
|
|
38
57
|
/** Minute steps that divide the hour. */
|
|
39
58
|
const MINUTE_STEPS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60];
|
|
40
59
|
|
|
60
|
+
/** A folded calendar stays mounted, so it comes back on the month and view it showed. */
|
|
61
|
+
const FOLDED = {
|
|
62
|
+
display: 'none'
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** The later / earlier of a limit and a bound; the bound when there's no limit. */
|
|
66
|
+
const later = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) > 0 ? a : b;
|
|
67
|
+
const earlier = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) < 0 ? a : b;
|
|
68
|
+
|
|
41
69
|
/**
|
|
42
70
|
* A date & time picker: a value field that opens a sheet (or an inline panel)
|
|
43
71
|
* with a calendar and, for date-time values, a time row. Single, range and
|
|
@@ -77,6 +105,7 @@ const DateTimePicker = props => {
|
|
|
77
105
|
disabled = false,
|
|
78
106
|
readOnly = false,
|
|
79
107
|
allowTyping,
|
|
108
|
+
hideCalendarOnKeyboard = true,
|
|
80
109
|
allowFieldTyping,
|
|
81
110
|
allowClear,
|
|
82
111
|
errorMessage,
|
|
@@ -108,6 +137,11 @@ const DateTimePicker = props => {
|
|
|
108
137
|
initialVisibleDate,
|
|
109
138
|
enableMonthSwipe = true,
|
|
110
139
|
calendarSystem,
|
|
140
|
+
calendarSwitch,
|
|
141
|
+
onCalendarSystemChange,
|
|
142
|
+
dualDefaultTab = 'gregory',
|
|
143
|
+
hijriLocale = 'ar-SA',
|
|
144
|
+
renderCalendarSwitch,
|
|
111
145
|
showToday = false,
|
|
112
146
|
showHolidays = true,
|
|
113
147
|
onVisibleMonthChange,
|
|
@@ -115,6 +149,7 @@ const DateTimePicker = props => {
|
|
|
115
149
|
validate,
|
|
116
150
|
yearRange: yearRangeProp = _types.DEFAULT_YEAR_RANGE,
|
|
117
151
|
locale,
|
|
152
|
+
numerals: numeralsProp,
|
|
118
153
|
timeZone,
|
|
119
154
|
now,
|
|
120
155
|
timeFormat: timeFormatProp,
|
|
@@ -144,6 +179,59 @@ const DateTimePicker = props => {
|
|
|
144
179
|
const firstDayOfWeek = firstDayProp ?? (0, _locale.deriveFirstDayOfWeek)(loc);
|
|
145
180
|
// Month and year picks are for single dates only.
|
|
146
181
|
const precision = type === 'date' && mode === 'single' ? precisionProp : 'day';
|
|
182
|
+
// The calendars the switch offers: none for month and year picks (always
|
|
183
|
+
// Gregorian), or when the platform has no Hijri calendar.
|
|
184
|
+
const switchKey = Array.isArray(calendarSwitch) ? calendarSwitch.join(',') : String(!!calendarSwitch);
|
|
185
|
+
const switchSystems = (0, _react.useMemo)(() => {
|
|
186
|
+
if (!calendarSwitch || precision !== 'day' || !(0, _calendarSystem.isHijriSupported)()) return null;
|
|
187
|
+
const list = calendarSwitch === true ? ALL_SYSTEMS : ALL_SYSTEMS.filter(x => calendarSwitch.includes(x)).sort((a, b) => calendarSwitch.indexOf(a) - calendarSwitch.indexOf(b));
|
|
188
|
+
return list.length > 1 ? list : null;
|
|
189
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the list is compared by content
|
|
190
|
+
}, [switchKey, precision]);
|
|
191
|
+
const startSystem = () => {
|
|
192
|
+
const wanted = calendarSystem ?? 'gregory';
|
|
193
|
+
return switchSystems && !switchSystems.includes(wanted) ? switchSystems[0] ?? wanted : wanted;
|
|
194
|
+
};
|
|
195
|
+
// The switch changes this; a new calendarSystem prop starts over from it.
|
|
196
|
+
const [chosenSystem, setChosenSystem] = (0, _react.useState)(startSystem);
|
|
197
|
+
// The calendar the props open on, which a value from outside counts as
|
|
198
|
+
// picked in. The switch's own choice coming back as the calendarSystem prop
|
|
199
|
+
// (onCalendarSystemChange={setSystem}) isn't a new one.
|
|
200
|
+
const [openedOn, setOpenedOn] = (0, _react.useState)(startSystem);
|
|
201
|
+
const echo = (0, _react.useRef)(null);
|
|
202
|
+
(0, _react.useEffect)(() => {
|
|
203
|
+
const next = startSystem();
|
|
204
|
+
const own = echo.current === next;
|
|
205
|
+
echo.current = null;
|
|
206
|
+
if (own) return;
|
|
207
|
+
setChosenSystem(next);
|
|
208
|
+
setOpenedOn(next);
|
|
209
|
+
},
|
|
210
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- only when the props change
|
|
211
|
+
[calendarSystem, switchKey]);
|
|
212
|
+
// Month and year picks are Gregorian whatever the calendar system.
|
|
213
|
+
const system = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(chosenSystem) : 'gregory';
|
|
214
|
+
// A dual calendar shows one of its two tabs; each open starts on dualDefaultTab.
|
|
215
|
+
const [dualTab, setDualTab] = (0, _react.useState)(dualDefaultTab);
|
|
216
|
+
/** The calendar on screen. */
|
|
217
|
+
const shownSystem = system === 'dual' ? dualTab : system;
|
|
218
|
+
// A value from outside counts as picked in the calendar the props open on,
|
|
219
|
+
// not the one the user has since chosen in the switch.
|
|
220
|
+
const propSystem = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(openedOn) : 'gregory';
|
|
221
|
+
const outsideSystem = propSystem === 'dual' ? dualDefaultTab : propSystem;
|
|
222
|
+
// Picks say which calendar they were made in only when one can be Hijri.
|
|
223
|
+
const hijriInPlay = switchSystems !== null || system !== 'gregory';
|
|
224
|
+
/**
|
|
225
|
+
* The digits for one calendar: a Hijri calendar (and a date picked in it)
|
|
226
|
+
* shows Arabic digits (١٢٣) in any language; a Gregorian one shows 0–9.
|
|
227
|
+
* `numerals` sets both.
|
|
228
|
+
*/
|
|
229
|
+
const digitsFor = sys => {
|
|
230
|
+
const kind = numeralsProp ?? (sys === 'hijri' ? 'arabic' : 'latin');
|
|
231
|
+
if (kind === 'arabic') return _numerals.arabicDigits;
|
|
232
|
+
if (kind === 'latin') return _numerals.latinDigits;
|
|
233
|
+
return (0, _numerals.localeDigits)(sys === 'hijri' ? hijriLocale : loc);
|
|
234
|
+
};
|
|
147
235
|
const monthNames = (0, _react.useMemo)(() => (0, _localeNames.localeNames)(loc).monthsLong, [loc]);
|
|
148
236
|
/** A month or year pick shown as text: "March 2026" or "2026". */
|
|
149
237
|
const periodText = v => {
|
|
@@ -207,7 +295,7 @@ const DateTimePicker = props => {
|
|
|
207
295
|
const {
|
|
208
296
|
isOpen: sheetOpen,
|
|
209
297
|
open,
|
|
210
|
-
close
|
|
298
|
+
close: closePicker
|
|
211
299
|
} = (0, _useOpenPicker.useOpenPicker)({
|
|
212
300
|
disabled,
|
|
213
301
|
readOnly,
|
|
@@ -217,7 +305,7 @@ const DateTimePicker = props => {
|
|
|
217
305
|
onClose
|
|
218
306
|
});
|
|
219
307
|
const isOpen = isInline || sheetOpen;
|
|
220
|
-
const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen);
|
|
308
|
+
const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen && hideCalendarOnKeyboard);
|
|
221
309
|
// The picker's own boxes that have focus. Inline, another field on the
|
|
222
310
|
// screen can raise the keyboard, so the calendar folds only for these.
|
|
223
311
|
const [focusedParts, setFocusedParts] = (0, _react.useState)({});
|
|
@@ -264,16 +352,36 @@ const DateTimePicker = props => {
|
|
|
264
352
|
};
|
|
265
353
|
})).catch(() => requestedYears.current.delete(year));
|
|
266
354
|
}, [loadHolidays]);
|
|
355
|
+
// A month's grid also shows days of the months either side, and a Hijri
|
|
356
|
+
// month can run from December into January, so a month at either end of a
|
|
357
|
+
// year loads the year next to it too.
|
|
358
|
+
const loadHolidaysAround = (0, _react.useCallback)((year, month) => {
|
|
359
|
+
loadHolidaysFor(year);
|
|
360
|
+
if (month >= 11 && year < yearRange.last) loadHolidaysFor(year + 1);
|
|
361
|
+
if (month === 1 && year > yearRange.first) loadHolidaysFor(year - 1);
|
|
362
|
+
}, [loadHolidaysFor, yearRange.first, yearRange.last]);
|
|
267
363
|
const holidays = (0, _react.useMemo)(() => [...(holidaysProp ?? []), ...Object.values(loadedHolidays).flat()], [holidaysProp, loadedHolidays]);
|
|
268
364
|
|
|
269
365
|
// Limits are worked out when the picker opens (the screen's own validation
|
|
270
366
|
// after Confirm stays the final check).
|
|
271
367
|
const weekdaysKey = disabledWeekdays?.join(',');
|
|
368
|
+
// Limits built with `dependsOnNow` ("from now on") are rebuilt every minute
|
|
369
|
+
// while the picker is open.
|
|
370
|
+
const [minuteTick, setMinuteTick] = (0, _react.useState)(0);
|
|
272
371
|
const constraints = (0, _react.useMemo)(() => {
|
|
273
372
|
const nowDate = now?.() ?? new Date();
|
|
373
|
+
// yearRange bounds the limits too, so days outside it are greyed.
|
|
274
374
|
const limits = {
|
|
275
|
-
minDate,
|
|
276
|
-
|
|
375
|
+
minDate: later(minDate, {
|
|
376
|
+
year: yearRange.first,
|
|
377
|
+
month: 1,
|
|
378
|
+
day: 1
|
|
379
|
+
}),
|
|
380
|
+
maxDate: earlier(maxDate, {
|
|
381
|
+
year: yearRange.last,
|
|
382
|
+
month: 12,
|
|
383
|
+
day: 31
|
|
384
|
+
}),
|
|
277
385
|
disabledDates,
|
|
278
386
|
enabledDates,
|
|
279
387
|
timeBounds,
|
|
@@ -296,8 +404,8 @@ const DateTimePicker = props => {
|
|
|
296
404
|
type,
|
|
297
405
|
timeZone: zone,
|
|
298
406
|
now: nowDate,
|
|
299
|
-
minDate,
|
|
300
|
-
maxDate,
|
|
407
|
+
minDate: limits.minDate,
|
|
408
|
+
maxDate: limits.maxDate,
|
|
301
409
|
isDisabled: disabledDates,
|
|
302
410
|
isEnabled: enabledDates,
|
|
303
411
|
timeBounds,
|
|
@@ -305,8 +413,25 @@ const DateTimePicker = props => {
|
|
|
305
413
|
holidays,
|
|
306
414
|
disableHolidays
|
|
307
415
|
});
|
|
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]);
|
|
416
|
+
// 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
|
|
417
|
+
}, [isOpen, today, minuteTick, type, zone, now, holidays, minDate, maxDate, disabledDates, enabledDates, timeBounds, weekdaysKey, disableHolidays, getConstraints, yearRange]);
|
|
418
|
+
const followsClock = isOpen && constraints.dependsOnNow;
|
|
419
|
+
(0, _react.useEffect)(() => {
|
|
420
|
+
if (!followsClock) return;
|
|
421
|
+
let timer;
|
|
422
|
+
const arm = () => {
|
|
423
|
+
const ms = 60_000 - (now?.() ?? new Date()).getTime() % 60_000;
|
|
424
|
+
timer = setTimeout(() => {
|
|
425
|
+
setMinuteTick(n => n + 1);
|
|
426
|
+
arm();
|
|
427
|
+
}, ms);
|
|
428
|
+
// Under Node (e.g. Jest) the timer must not keep the process alive.
|
|
429
|
+
timer.unref?.();
|
|
430
|
+
};
|
|
431
|
+
arm();
|
|
432
|
+
return () => clearTimeout(timer);
|
|
433
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- armed while open with a clock-bound limit
|
|
434
|
+
}, [followsClock]);
|
|
310
435
|
|
|
311
436
|
// A typed field that doesn't parse blocks Confirm, per field: one end of a
|
|
312
437
|
// range can't hide the other end's problem.
|
|
@@ -333,14 +458,30 @@ const DateTimePicker = props => {
|
|
|
333
458
|
const [wheelSpinning, setWheelSpinning] = (0, _react.useState)(false);
|
|
334
459
|
// From/To layout: the end that calendar taps fill. perDate: the day the time row edits.
|
|
335
460
|
const [activeEnd, setActiveEnd] = (0, _react.useState)('from');
|
|
461
|
+
// From/To layout: a From or To field was tapped, so the next day tap edits that end only.
|
|
462
|
+
const [endPicked, setEndPicked] = (0, _react.useState)(false);
|
|
463
|
+
const activateEnd = (0, _react.useCallback)(end => {
|
|
464
|
+
setActiveEnd(end);
|
|
465
|
+
setEndPicked(true);
|
|
466
|
+
}, []);
|
|
336
467
|
const [activeDay, setActiveDay] = (0, _react.useState)(null);
|
|
337
468
|
const resetSelectionUi = (0, _react.useCallback)(() => {
|
|
469
|
+
// What was typed is gone with the selection, so nothing blocks Confirm.
|
|
470
|
+
setTypingBlocks({});
|
|
338
471
|
setPendingTimes({});
|
|
339
472
|
setActiveEnd('from');
|
|
473
|
+
setEndPicked(false);
|
|
340
474
|
setActiveDay(null);
|
|
341
475
|
}, []);
|
|
476
|
+
// A day in the month the calendar last showed, so a switch to the other
|
|
477
|
+
// calendar opens on the same days. Each open starts from the value again.
|
|
478
|
+
const shownAnchor = (0, _react.useRef)(null);
|
|
479
|
+
const rememberAnchor = (0, _react.useCallback)(day => {
|
|
480
|
+
shownAnchor.current = day;
|
|
481
|
+
}, []);
|
|
342
482
|
// Opening or closing starts fresh: nothing edited, nothing blocked.
|
|
343
483
|
(0, _react.useEffect)(() => {
|
|
484
|
+
shownAnchor.current = null;
|
|
344
485
|
edited.current = false;
|
|
345
486
|
setTypingBlocks({});
|
|
346
487
|
setTimeCheck(0);
|
|
@@ -404,6 +545,59 @@ const DateTimePicker = props => {
|
|
|
404
545
|
};
|
|
405
546
|
const valueKey = JSON.stringify(value ?? '');
|
|
406
547
|
|
|
548
|
+
// A selection belongs to the calendar it was picked in (Gregorian or Hijri):
|
|
549
|
+
// it shows only there, and the field writes it in that calendar. A saved
|
|
550
|
+
// value remembers its calendar; one from outside counts as picked in the
|
|
551
|
+
// calendar the picker opens on.
|
|
552
|
+
// The saved value as a draft, for the on-screen field and for comparing
|
|
553
|
+
// values by what they hold.
|
|
554
|
+
const saved = (0, _react.useMemo)(() => (0, _draft.createDraft)(mode, value, draftOptions),
|
|
555
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the value is compared by content (`valueKey`)
|
|
556
|
+
[valueKey, mode, draftOptions]);
|
|
557
|
+
/** A draft's days and times, so a value written another way ({to, from}) still matches. */
|
|
558
|
+
const contentOf = dr => JSON.stringify(valuesOf(dr));
|
|
559
|
+
const savedContent = contentOf(saved);
|
|
560
|
+
const savedSystemRef = (0, _react.useRef)(null);
|
|
561
|
+
const savedSystem = savedSystemRef.current?.content === savedContent ? savedSystemRef.current.system : outsideSystem;
|
|
562
|
+
const [draftSystem, setDraftSystem] = (0, _react.useState)(savedSystem);
|
|
563
|
+
// The draft is rebuilt on open and on a new value; so is its calendar. A new
|
|
564
|
+
// calendarSystem prop while the user is picking starts the selection over,
|
|
565
|
+
// since a selection is one calendar's.
|
|
566
|
+
const systemSeen = (0, _react.useRef)({
|
|
567
|
+
isOpen,
|
|
568
|
+
valueKey,
|
|
569
|
+
savedSystem
|
|
570
|
+
});
|
|
571
|
+
(0, _react.useEffect)(() => {
|
|
572
|
+
const seen = systemSeen.current;
|
|
573
|
+
systemSeen.current = {
|
|
574
|
+
isOpen,
|
|
575
|
+
valueKey,
|
|
576
|
+
savedSystem
|
|
577
|
+
};
|
|
578
|
+
setDraftSystem(savedSystem);
|
|
579
|
+
const systemOnly = seen.isOpen === isOpen && seen.valueKey === valueKey && seen.savedSystem !== savedSystem;
|
|
580
|
+
if (systemOnly && isOpen && edited.current) {
|
|
581
|
+
draft.clear();
|
|
582
|
+
resetSelectionUi();
|
|
583
|
+
}
|
|
584
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the draft's actions are stable
|
|
585
|
+
}, [isOpen, valueKey, savedSystem]);
|
|
586
|
+
(0, _react.useEffect)(() => setDualTab(dualDefaultTab), [isOpen, dualDefaultTab]);
|
|
587
|
+
const selectionShown = draftSystem === shownSystem;
|
|
588
|
+
/** Saves a value: with the calendar it was picked in, when one can be Hijri. */
|
|
589
|
+
const emitChange = (0, _react.useCallback)((wire, picked) => {
|
|
590
|
+
savedSystemRef.current = {
|
|
591
|
+
content: contentOf((0, _draft.createDraft)(mode, wire, draftOptions)),
|
|
592
|
+
system: picked
|
|
593
|
+
};
|
|
594
|
+
if (hijriInPlay) onChange(wire, {
|
|
595
|
+
calendarSystem: picked
|
|
596
|
+
});else onChange(wire);
|
|
597
|
+
},
|
|
598
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- contentOf reads only `type` and the options listed
|
|
599
|
+
[hijriInPlay, onChange, mode, draftOptions]);
|
|
600
|
+
|
|
407
601
|
/**
|
|
408
602
|
* Whether a draft can be saved as it stands: complete, every day allowed,
|
|
409
603
|
* every time allowed and on the minute step, and nothing being typed or
|
|
@@ -416,19 +610,19 @@ const DateTimePicker = props => {
|
|
|
416
610
|
|
|
417
611
|
// Every save: Confirm, an 'instant' edit (onConfirm is added by `confirm`).
|
|
418
612
|
const commit = (0, _react.useCallback)(wire => {
|
|
419
|
-
|
|
613
|
+
emitChange(wire, draftSystem);
|
|
420
614
|
onBlur?.();
|
|
421
|
-
}, [
|
|
615
|
+
}, [emitChange, draftSystem, onBlur]);
|
|
422
616
|
const confirm = (0, _react.useCallback)(() => {
|
|
423
617
|
if (!canConfirm) return;
|
|
424
618
|
const {
|
|
425
619
|
validate: check,
|
|
426
620
|
onError: report,
|
|
427
|
-
value:
|
|
621
|
+
value: current
|
|
428
622
|
} = latest.current;
|
|
429
623
|
if (timeBlocked) {
|
|
430
624
|
setTimeCheck(n => n + 1);
|
|
431
|
-
report?.(timeIssue ?? 'TIME_NOT_ALLOWED',
|
|
625
|
+
report?.(timeIssue ?? 'TIME_NOT_ALLOWED', current);
|
|
432
626
|
return;
|
|
433
627
|
}
|
|
434
628
|
const wire = (0, _draft.draftToWire)(preview, draftOptions);
|
|
@@ -444,14 +638,14 @@ const DateTimePicker = props => {
|
|
|
444
638
|
commit(wire);
|
|
445
639
|
onConfirm?.(wire);
|
|
446
640
|
edited.current = false;
|
|
447
|
-
if (!isInline)
|
|
448
|
-
}, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline,
|
|
641
|
+
if (!isInline) closePicker();
|
|
642
|
+
}, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline, closePicker]);
|
|
449
643
|
const clearValue = (0, _react.useCallback)(() => {
|
|
450
644
|
draft.clear();
|
|
451
645
|
resetSelectionUi();
|
|
452
646
|
edited.current = false;
|
|
453
|
-
|
|
454
|
-
}, [draft,
|
|
647
|
+
emitChange('', draftSystem);
|
|
648
|
+
}, [draft, emitChange, draftSystem, resetSelectionUi]);
|
|
455
649
|
const clearDraft = (0, _react.useCallback)(() => {
|
|
456
650
|
edited.current = true;
|
|
457
651
|
draft.clear();
|
|
@@ -460,9 +654,10 @@ const DateTimePicker = props => {
|
|
|
460
654
|
|
|
461
655
|
// × in the field above the calendar. 'instant' saves every edit, so it
|
|
462
656
|
// clears the saved value too (once; an empty value isn't saved again).
|
|
657
|
+
const hasSaved = valuesOf(saved).some(v => v !== null);
|
|
463
658
|
const clearInSheet = (0, _react.useCallback)(() => {
|
|
464
|
-
if (commitMode === 'instant' &&
|
|
465
|
-
}, [commitMode,
|
|
659
|
+
if (commitMode === 'instant' && hasSaved) clearValue();else clearDraft();
|
|
660
|
+
}, [commitMode, hasSaved, clearValue, clearDraft]);
|
|
466
661
|
|
|
467
662
|
// Opening or closing starts without the last `validate` message.
|
|
468
663
|
(0, _react.useEffect)(() => setValidation(null), [isOpen]);
|
|
@@ -473,15 +668,27 @@ const DateTimePicker = props => {
|
|
|
473
668
|
// An edit equal to the saved value isn't saved again; one `validate`
|
|
474
669
|
// rejected waits until the selection or the saved value changes.
|
|
475
670
|
const lastRejected = (0, _react.useRef)(null);
|
|
671
|
+
// The last value saved: not saved again while the parent's `value` catches
|
|
672
|
+
// up (a slow store, a server round trip) or when it never does.
|
|
673
|
+
const lastEmitted = (0, _react.useRef)(null);
|
|
476
674
|
(0, _react.useEffect)(() => {
|
|
477
675
|
lastRejected.current = null;
|
|
478
|
-
|
|
479
|
-
|
|
676
|
+
lastEmitted.current = null;
|
|
677
|
+
}, [valueKey, isOpen]);
|
|
678
|
+
// The field in the sheet saves once typing there is done (focus leaves it),
|
|
679
|
+
// so 09:30 isn't saved as 09:00 and 09:03 on the way.
|
|
680
|
+
const sheetTyping = !!(focusedParts.value || focusedParts['value-from'] || focusedParts['value-to']);
|
|
681
|
+
/** Saves the draft in instant mode; `typingDone` once the sheet's field is left. */
|
|
682
|
+
const saveInstant = typingDone => {
|
|
480
683
|
if (commitMode !== 'instant' || !isOpen || !edited.current) return;
|
|
481
|
-
if (timeIssue || !canSave(draft.draft)) return;
|
|
684
|
+
if (!typingDone || timeIssue || !canSave(draft.draft)) return;
|
|
482
685
|
const wire = draft.toWire();
|
|
483
686
|
const key = JSON.stringify(wire);
|
|
484
|
-
if (key ===
|
|
687
|
+
if (key === lastRejected.current || key === lastEmitted.current) return;
|
|
688
|
+
// The same dates picked in the same calendar aren't saved again; the same
|
|
689
|
+
// dates picked in the other calendar are.
|
|
690
|
+
const unchanged = key === valueKey || contentOf(draft.draft) === savedContent;
|
|
691
|
+
if (unchanged && draftSystem === savedSystem) return;
|
|
485
692
|
const message = latest.current.validate?.(wire);
|
|
486
693
|
if (message) {
|
|
487
694
|
lastRejected.current = key;
|
|
@@ -492,9 +699,22 @@ const DateTimePicker = props => {
|
|
|
492
699
|
latest.current.onError?.('VALIDATION', wire);
|
|
493
700
|
return;
|
|
494
701
|
}
|
|
702
|
+
lastEmitted.current = key;
|
|
495
703
|
commit(wire);
|
|
496
|
-
|
|
497
|
-
|
|
704
|
+
};
|
|
705
|
+
// Only typing waits for the field to be left; a tap is a finished edit.
|
|
706
|
+
const typedLast = (0, _react.useRef)(false);
|
|
707
|
+
(0, _react.useEffect)(() => saveInstant(!sheetTyping || !typedLast.current),
|
|
708
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- when the draft or what blocks it changes, not when callbacks are re-created
|
|
709
|
+
[commitMode, isOpen, sheetTyping, draft.draft, draftSystem, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
|
|
710
|
+
// Closing while the sheet's field still has focus ends the typing: an
|
|
711
|
+
// instant picker saves what was typed before it closes.
|
|
712
|
+
const saveInstantRef = (0, _react.useRef)(saveInstant);
|
|
713
|
+
saveInstantRef.current = saveInstant;
|
|
714
|
+
const close = (0, _react.useCallback)(() => {
|
|
715
|
+
saveInstantRef.current(true);
|
|
716
|
+
closePicker();
|
|
717
|
+
}, [closePicker]);
|
|
498
718
|
|
|
499
719
|
// A typed date with no time yet gets one the way a tapped day does: the fixed
|
|
500
720
|
// newDayTime, else a time already typed in the time row, else now.
|
|
@@ -502,14 +722,24 @@ const DateTimePicker = props => {
|
|
|
502
722
|
date: parsed.dateOnly,
|
|
503
723
|
time: fixedTime ?? pending[key] ?? nowTime()
|
|
504
724
|
} : null);
|
|
725
|
+
|
|
726
|
+
// Typed segments are Gregorian, so typing keeps the calendar a selection was
|
|
727
|
+
// picked in; into an empty draft, it takes the calendar on screen.
|
|
728
|
+
const adoptShownIfEmpty = () => {
|
|
729
|
+
if (valuesOf(d).every(v => v === null)) setDraftSystem(shownSystem);
|
|
730
|
+
};
|
|
505
731
|
const onSheetTyped = parsed => {
|
|
506
732
|
edited.current = true;
|
|
733
|
+
typedLast.current = true;
|
|
734
|
+
adoptShownIfEmpty();
|
|
507
735
|
const typed = withFilledTime(parsed, 'single');
|
|
508
736
|
setTypingBlock('single', !parsed.isEmpty && !typed);
|
|
509
737
|
if (typed) draft.setValue(typed, 'single');else if (parsed.isEmpty) draft.clear();
|
|
510
738
|
};
|
|
511
739
|
const onRangeTyped = (end, parsed) => {
|
|
512
740
|
edited.current = true;
|
|
741
|
+
typedLast.current = true;
|
|
742
|
+
adoptShownIfEmpty();
|
|
513
743
|
const typed = withFilledTime(parsed, end);
|
|
514
744
|
setTypingBlock(end, !parsed.isEmpty && !typed);
|
|
515
745
|
if (typed || parsed.isEmpty) draft.setValue(typed, end);
|
|
@@ -530,28 +760,77 @@ const DateTimePicker = props => {
|
|
|
530
760
|
minute: capped % 60
|
|
531
761
|
};
|
|
532
762
|
}, [now, zone, minuteStep]);
|
|
763
|
+
|
|
764
|
+
// A range end picked on the start's day starts an hour after the start (at
|
|
765
|
+
// most the day's latest allowed time, or its last step), so the range isn't
|
|
766
|
+
// out of order before the user has touched the time.
|
|
767
|
+
// A time typed for the end before its day is kept as typed.
|
|
768
|
+
const endTimeFor = (from, day, typed) => {
|
|
769
|
+
if (!fixedTime && typed) return typed;
|
|
770
|
+
const time = fixedTime ?? nowTime();
|
|
771
|
+
if (!from?.time || !(0, _calendarDate.isSameDay)(from.date, day)) return time;
|
|
772
|
+
const start = from.time.hour * 60 + from.time.minute;
|
|
773
|
+
if (time.hour * 60 + time.minute > start) return time;
|
|
774
|
+
// Within the day's allowed hours when it has them.
|
|
775
|
+
const max = constraints.timeBounds(day)?.max;
|
|
776
|
+
const last = max ? max.hour * 60 + max.minute : 24 * 60 - Math.max(1, minuteStep);
|
|
777
|
+
const end = Math.min(start + 60, last);
|
|
778
|
+
return {
|
|
779
|
+
hour: Math.floor(end / 60),
|
|
780
|
+
minute: end % 60
|
|
781
|
+
};
|
|
782
|
+
};
|
|
533
783
|
const onSelectDay = (0, _react.useCallback)(day => {
|
|
534
784
|
edited.current = true;
|
|
535
|
-
|
|
785
|
+
typedLast.current = false;
|
|
786
|
+
// A pick in the other calendar starts over: the selection is one calendar's.
|
|
787
|
+
const fresh = draftSystem !== shownSystem && valuesOf(d).some(v => v !== null);
|
|
788
|
+
setDraftSystem(shownSystem);
|
|
789
|
+
const cur = fresh ? (0, _draft.clearDraft)(d) : d;
|
|
790
|
+
const end0 = fresh ? 'from' : activeEnd;
|
|
791
|
+
const dayInEdit = fresh ? null : activeDay;
|
|
792
|
+
const times = fresh ? {} : pending;
|
|
793
|
+
if (fresh) {
|
|
794
|
+
draft.clear();
|
|
795
|
+
resetSelectionUi();
|
|
796
|
+
}
|
|
797
|
+
if (cur.mode === 'range') {
|
|
536
798
|
if (rangeLayout === 'fromTo') {
|
|
799
|
+
setEndPicked(false);
|
|
800
|
+
// A full range: the tap starts a new one (or moves the nearest end).
|
|
801
|
+
if (!endPicked && cur.from.value && cur.to.value) {
|
|
802
|
+
const moveNearest = range?.reselect === 'moveNearestEnd';
|
|
803
|
+
const nearest = Math.abs((0, _calendarDate.daysBetween)(cur.from.value.date, day)) < Math.abs((0, _calendarDate.daysBetween)(cur.to.value.date, day)) ? 'from' : 'to';
|
|
804
|
+
const end = moveNearest ? nearest : 'from';
|
|
805
|
+
setTypingBlock('from', false);
|
|
806
|
+
setTypingBlock('to', false);
|
|
807
|
+
draft.selectDay(day, fixedTime ?? times[end] ?? nowTime());
|
|
808
|
+
setActiveEnd(moveNearest ? nearest : 'to');
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
// Choosing the end after a start tap: a day before the start moves the start.
|
|
812
|
+
const end1 = end0 === 'to' && !endPicked && cur.from.value && (0, _calendarDate.compareCalendarDates)(day, cur.from.value.date) < 0 ? 'from' : end0;
|
|
537
813
|
// The tapped day replaces whatever was typed in this end only.
|
|
538
|
-
setTypingBlock(
|
|
539
|
-
draft.setRangeEnd(day,
|
|
540
|
-
|
|
814
|
+
setTypingBlock(end1, false);
|
|
815
|
+
draft.setRangeEnd(day, end1, end1 === 'to' ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times.from ?? nowTime());
|
|
816
|
+
// The start tapped again where a range can't be one day deselects
|
|
817
|
+
// it, so the next tap picks the start again.
|
|
818
|
+
const deselects = end1 === 'to' && !(0, _draft.sameDayRangeOk)(draftOptions) && (0, _calendarDate.isSameDay)(cur.from.value?.date, day);
|
|
819
|
+
if (end0 === 'from') setActiveEnd('to');else if (deselects) setActiveEnd('from');
|
|
541
820
|
return;
|
|
542
821
|
}
|
|
543
822
|
// The single field: the first tap is the start, the next one the end.
|
|
544
|
-
const startsOver = !
|
|
823
|
+
const startsOver = !cur.from.value || !!cur.to.value && range?.reselect !== 'moveNearestEnd';
|
|
545
824
|
const end = startsOver ? 'from' : 'to';
|
|
546
825
|
setTypingBlock('single', false);
|
|
547
|
-
draft.selectDay(day, fixedTime ??
|
|
826
|
+
draft.selectDay(day, end === 'to' && !cur.to.value ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times[end] ?? nowTime());
|
|
548
827
|
return;
|
|
549
828
|
}
|
|
550
|
-
if (
|
|
829
|
+
if (cur.mode === 'multiple') {
|
|
551
830
|
const perDate = type === 'datetime' && multipleTimeMode === 'perDate';
|
|
552
|
-
const picked =
|
|
831
|
+
const picked = cur.slots.some(slot => (0, _calendarDate.isSameDay)(slot.value?.date, day));
|
|
553
832
|
// perDate: a tap on a picked day first makes it the one the time row edits.
|
|
554
|
-
if (perDate && picked && !(0, _calendarDate.isSameDay)(
|
|
833
|
+
if (perDate && picked && !(0, _calendarDate.isSameDay)(dayInEdit, day)) {
|
|
555
834
|
setActiveDay(day);
|
|
556
835
|
return;
|
|
557
836
|
}
|
|
@@ -560,18 +839,28 @@ const DateTimePicker = props => {
|
|
|
560
839
|
return;
|
|
561
840
|
}
|
|
562
841
|
setTypingBlock('single', false);
|
|
563
|
-
draft.selectDay(day, fixedTime ??
|
|
564
|
-
},
|
|
842
|
+
draft.selectDay(day, fixedTime ?? times.single ?? nowTime());
|
|
843
|
+
},
|
|
844
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- valuesOf reads only `d` and props listed here
|
|
845
|
+
[d, draft, nowTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock, draftSystem, shownSystem, resetSelectionUi, endPicked, draftOptions, minuteStep, constraints]);
|
|
846
|
+
|
|
847
|
+
// The calendar gets a tap handler that never changes, so its memoized day
|
|
848
|
+
// cells don't all redraw on every tap; it calls the current one.
|
|
849
|
+
const selectDayRef = (0, _react.useRef)(onSelectDay);
|
|
850
|
+
selectDayRef.current = onSelectDay;
|
|
851
|
+
const onSelectDayStable = (0, _react.useCallback)(day => selectDayRef.current(day), []);
|
|
565
852
|
|
|
566
853
|
// Greying that depends on what's picked: range length, From/To order, the multiple cap.
|
|
567
854
|
const calendarConstraints = (0, _react.useMemo)(() => {
|
|
568
855
|
if (d.mode === 'range') {
|
|
569
|
-
|
|
856
|
+
// A full From/To range greys nothing: the next tap starts a new one.
|
|
857
|
+
const choosingEnd = rangeLayout === 'fromTo' ? activeEnd === 'to' && (endPicked || !d.to.value) : !!d.from.value && !d.to.value;
|
|
570
858
|
return (0, _selectionRules.withSelectionRules)(constraints, {
|
|
571
859
|
rangeStart: choosingEnd ? d.from.value?.date : null,
|
|
572
860
|
minDays: range?.minDays,
|
|
573
861
|
maxDays: range?.maxDays,
|
|
574
|
-
|
|
862
|
+
// Only an end chosen from the To field can't go before the start.
|
|
863
|
+
blockBeforeStart: rangeLayout === 'fromTo' && endPicked
|
|
575
864
|
});
|
|
576
865
|
}
|
|
577
866
|
if (d.mode === 'multiple') {
|
|
@@ -582,7 +871,7 @@ const DateTimePicker = props => {
|
|
|
582
871
|
});
|
|
583
872
|
}
|
|
584
873
|
return constraints;
|
|
585
|
-
}, [constraints, d, rangeLayout, activeEnd, range?.minDays, range?.maxDays, multiple?.maxSelections]);
|
|
874
|
+
}, [constraints, d, rangeLayout, activeEnd, endPicked, range?.minDays, range?.maxDays, multiple?.maxSelections]);
|
|
586
875
|
const selection = draft.draft.mode === 'single' ? {
|
|
587
876
|
kind: 'single',
|
|
588
877
|
day: draft.draft.slot.value?.date ?? null
|
|
@@ -609,13 +898,13 @@ const DateTimePicker = props => {
|
|
|
609
898
|
}
|
|
610
899
|
}, [isOpen, constraints, today]);
|
|
611
900
|
const handleVisibleMonth = (0, _react.useCallback)((year, month) => {
|
|
612
|
-
|
|
901
|
+
loadHolidaysAround(year, month);
|
|
613
902
|
onVisibleMonthChange?.(year, month);
|
|
614
|
-
}, [
|
|
903
|
+
}, [loadHolidaysAround, onVisibleMonthChange]);
|
|
615
904
|
(0, _react.useEffect)(() => {
|
|
616
905
|
if (!isOpen) return;
|
|
617
|
-
const anchor = selection.kind === 'single' ? selection.day : null;
|
|
618
|
-
|
|
906
|
+
const anchor = (selection.kind === 'single' ? selection.day : null) ?? today;
|
|
907
|
+
loadHolidaysAround(anchor.year, anchor.month);
|
|
619
908
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- once per open
|
|
620
909
|
}, [isOpen]);
|
|
621
910
|
|
|
@@ -666,17 +955,19 @@ const DateTimePicker = props => {
|
|
|
666
955
|
return;
|
|
667
956
|
}
|
|
668
957
|
setTriggerError('');
|
|
669
|
-
|
|
958
|
+
// Typing keeps the calendar the saved value was picked in.
|
|
959
|
+
emitChange(wire, savedSystem);
|
|
670
960
|
onBlur?.();
|
|
671
961
|
};
|
|
672
962
|
|
|
963
|
+
/** A value's date in the calendar it was picked in: Hijri text, or none for the dateFormat. */
|
|
964
|
+
const dateTextFor = picked => picked === 'hijri' ? v => (0, _calendarSystem.hijriDateText)(v.date, hijriLocale) ?? (0, _fieldText.formatDateText)(v, dateFormat) : undefined;
|
|
965
|
+
const savedDateText = dateTextFor(savedSystem);
|
|
966
|
+
const draftDateText = dateTextFor(draftSystem);
|
|
967
|
+
|
|
673
968
|
// 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
969
|
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;
|
|
970
|
+
const savedText = saved.mode === 'range' ? (0, _fieldText.formatRangeText)(saved.from.value, saved.to.value, type, dateFormat, timeFormat, strings.rangeSeparator, savedDateText, strings) : saved.mode === 'multiple' ? (0, _fieldText.formatMultipleText)(saved.slots.map(slot => slot.value), type, dateFormat, timeFormat, savedDateText, strings) : precision !== 'day' ? periodText(savedSingle) : undefined;
|
|
680
971
|
const periodPlaceholder = precision === 'year' ? strings.placeholderYear : precision === 'month' ? `${strings.placeholderMonth} ${strings.placeholderYear}` : undefined;
|
|
681
972
|
|
|
682
973
|
// The time a custom renderTimeRow edits, and how it sets it (the same
|
|
@@ -702,7 +993,7 @@ const DateTimePicker = props => {
|
|
|
702
993
|
type,
|
|
703
994
|
mode,
|
|
704
995
|
value,
|
|
705
|
-
displayText: savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat),
|
|
996
|
+
displayText: digitsFor(savedSystem)(savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat, savedDateText, strings)),
|
|
706
997
|
disabled,
|
|
707
998
|
readOnly,
|
|
708
999
|
isOpen,
|
|
@@ -745,6 +1036,7 @@ const DateTimePicker = props => {
|
|
|
745
1036
|
...fieldCommon,
|
|
746
1037
|
value: savedSingle,
|
|
747
1038
|
displayText: savedText,
|
|
1039
|
+
dateText: savedDateText,
|
|
748
1040
|
allowTyping: mode === 'single' && precision === 'day' && allowFieldTyping,
|
|
749
1041
|
onTypingDone: onTriggerTyped,
|
|
750
1042
|
onTyped: () => setTriggerError(''),
|
|
@@ -776,6 +1068,7 @@ const DateTimePicker = props => {
|
|
|
776
1068
|
...fieldCommon,
|
|
777
1069
|
value: sheetValue,
|
|
778
1070
|
displayText: precision !== 'day' ? periodText(sheetValue) : undefined,
|
|
1071
|
+
dateText: draftDateText,
|
|
779
1072
|
placeholder: sheetOptions?.fieldPlaceholder ?? periodPlaceholder,
|
|
780
1073
|
allowTyping: allowTyping && precision === 'day',
|
|
781
1074
|
onTyped: onSheetTyped,
|
|
@@ -789,12 +1082,13 @@ const DateTimePicker = props => {
|
|
|
789
1082
|
}) : d.mode === 'range' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_RangeFields.default, {
|
|
790
1083
|
...fieldCommon,
|
|
791
1084
|
layout: rangeLayout,
|
|
1085
|
+
dateText: draftDateText,
|
|
792
1086
|
showIcon: sheetOptions?.fieldIcon,
|
|
793
1087
|
from: d.from.value,
|
|
794
1088
|
to: d.to.value,
|
|
795
1089
|
placeholder: sheetOptions?.fieldPlaceholder,
|
|
796
1090
|
activeEnd: activeEnd,
|
|
797
|
-
onActivate:
|
|
1091
|
+
onActivate: activateEnd,
|
|
798
1092
|
allowTyping: allowTyping,
|
|
799
1093
|
onTyped: onRangeTyped,
|
|
800
1094
|
onFocusChange: (end, f) => reportFocus(`value-${end}`, f),
|
|
@@ -806,7 +1100,7 @@ const DateTimePicker = props => {
|
|
|
806
1100
|
}) : d.mode === 'multiple' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
|
|
807
1101
|
...fieldCommon,
|
|
808
1102
|
value: null,
|
|
809
|
-
displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat),
|
|
1103
|
+
displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat, draftDateText, strings),
|
|
810
1104
|
placeholder: sheetOptions?.fieldPlaceholder,
|
|
811
1105
|
allowClear: allowClear,
|
|
812
1106
|
onClear: clearInSheet,
|
|
@@ -815,37 +1109,92 @@ const DateTimePicker = props => {
|
|
|
815
1109
|
active: true,
|
|
816
1110
|
testID: testID ? `${testID}-value` : undefined
|
|
817
1111
|
}) : 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
|
-
|
|
1112
|
+
const systemLabels = {
|
|
1113
|
+
gregory: strings.calendarGregorian ?? _defaultStrings.DEFAULT_STRINGS.calendarGregorian,
|
|
1114
|
+
hijri: strings.calendarHijri ?? _defaultStrings.DEFAULT_STRINGS.calendarHijri,
|
|
1115
|
+
dual: strings.calendarDual ?? _defaultStrings.DEFAULT_STRINGS.calendarDual
|
|
1116
|
+
};
|
|
1117
|
+
const systemA11yLabel = strings.a11yCalendarSystem ?? _defaultStrings.DEFAULT_STRINGS.a11yCalendarSystem;
|
|
1118
|
+
const chooseSystem = next => {
|
|
1119
|
+
if (next === system) return;
|
|
1120
|
+
setChosenSystem(next);
|
|
1121
|
+
if (next === 'dual') setDualTab(dualDefaultTab);
|
|
1122
|
+
echo.current = next;
|
|
1123
|
+
onCalendarSystemChange?.(next);
|
|
1124
|
+
};
|
|
1125
|
+
const calendarSwitchNode = !switchSystems ? null : renderCalendarSwitch ? renderCalendarSwitch({
|
|
1126
|
+
systems: switchSystems,
|
|
1127
|
+
selected: system,
|
|
1128
|
+
onSelect: chooseSystem,
|
|
1129
|
+
tokens,
|
|
1130
|
+
strings
|
|
1131
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
|
|
1132
|
+
variant: "switch",
|
|
1133
|
+
options: switchSystems.map(v => {
|
|
1134
|
+
return {
|
|
1135
|
+
value: v,
|
|
1136
|
+
label: systemLabels[v]
|
|
1137
|
+
};
|
|
1138
|
+
}),
|
|
1139
|
+
selected: system,
|
|
1140
|
+
onSelect: chooseSystem,
|
|
1141
|
+
accessibilityLabel: systemA11yLabel,
|
|
845
1142
|
tokens: tokens,
|
|
846
1143
|
styles: styles,
|
|
847
|
-
|
|
848
|
-
|
|
1144
|
+
testID: testID ? `${testID}-calendar-switch` : undefined
|
|
1145
|
+
});
|
|
1146
|
+
const dualTabs = system !== 'dual' ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
|
|
1147
|
+
variant: "tabs",
|
|
1148
|
+
options: [{
|
|
1149
|
+
value: 'gregory',
|
|
1150
|
+
label: systemLabels.gregory
|
|
1151
|
+
}, {
|
|
1152
|
+
value: 'hijri',
|
|
1153
|
+
label: systemLabels.hijri
|
|
1154
|
+
}],
|
|
1155
|
+
selected: dualTab,
|
|
1156
|
+
onSelect: setDualTab,
|
|
1157
|
+
accessibilityLabel: systemA11yLabel,
|
|
1158
|
+
tokens: tokens,
|
|
1159
|
+
styles: styles,
|
|
1160
|
+
testID: testID ? `${testID}-dual-tabs` : undefined
|
|
1161
|
+
});
|
|
1162
|
+
// Another calendar opens on the days the last one showed, else on the
|
|
1163
|
+
// selection (shown or not), else where the picker would open.
|
|
1164
|
+
const calendarAnchor = shownAnchor.current ?? (selectionShown ? null : (0, _selection.firstSelectedDay)(selection)) ?? initialVisibleDate;
|
|
1165
|
+
const calendar = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1166
|
+
style: folded ? FOLDED : undefined,
|
|
1167
|
+
children: [calendarSwitchNode, dualTabs, /*#__PURE__*/(0, _jsxRuntime.jsx)(_Calendar.default, {
|
|
1168
|
+
constraints: selectionShown ? calendarConstraints : constraints,
|
|
1169
|
+
today: today,
|
|
1170
|
+
initialVisibleDate: calendarAnchor,
|
|
1171
|
+
selection: selectionShown ? selection : emptySelection(selection),
|
|
1172
|
+
onSelectDay: onSelectDayStable,
|
|
1173
|
+
firstDayOfWeek: firstDayOfWeek,
|
|
1174
|
+
showOutsideDays: showOutsideDays,
|
|
1175
|
+
showHolidays: showHolidays,
|
|
1176
|
+
yearRange: yearRange,
|
|
1177
|
+
locale: shownSystem === 'hijri' ? hijriLocale : loc,
|
|
1178
|
+
calendarSystem: shownSystem,
|
|
1179
|
+
initialView: initialView,
|
|
1180
|
+
precision: precision,
|
|
1181
|
+
enableMonthSwipe: enableMonthSwipe,
|
|
1182
|
+
showToday: showToday,
|
|
1183
|
+
onVisibleMonthChange: handleVisibleMonth,
|
|
1184
|
+
onAnchorChange: rememberAnchor,
|
|
1185
|
+
renderDay: renderDay,
|
|
1186
|
+
renderWeekday: renderWeekday,
|
|
1187
|
+
renderMonthChip: renderMonthChip,
|
|
1188
|
+
renderYearCell: renderYearCell,
|
|
1189
|
+
renderMonthCell: renderMonthCell,
|
|
1190
|
+
renderEmptyState: renderEmptyState,
|
|
1191
|
+
icons: icons,
|
|
1192
|
+
iconProps: iconProps,
|
|
1193
|
+
tokens: tokens,
|
|
1194
|
+
styles: styles,
|
|
1195
|
+
strings: strings,
|
|
1196
|
+
testID: testID
|
|
1197
|
+
}, shownSystem)]
|
|
849
1198
|
});
|
|
850
1199
|
const timeRow = type !== 'datetime' ? null : renderTimeRow ? renderTimeRow(state) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_TimeRows.default, {
|
|
851
1200
|
draft: d,
|
|
@@ -878,8 +1227,20 @@ const DateTimePicker = props => {
|
|
|
878
1227
|
|
|
879
1228
|
// Shown while the selection is still the one it was given for.
|
|
880
1229
|
const validationMessage = validation && (validation.key === JSON.stringify(draft.toWire()) || validation.key === JSON.stringify((0, _draft.draftToWire)(preview, draftOptions))) ? validation.message : null;
|
|
1230
|
+
|
|
1231
|
+
// The field and the time row write the date in the digits of the calendar
|
|
1232
|
+
// it was picked in; the calendar uses its own.
|
|
881
1233
|
const sheetContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
882
|
-
children: [
|
|
1234
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1235
|
+
value: digitsFor(draftSystem),
|
|
1236
|
+
children: sheetField
|
|
1237
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1238
|
+
value: digitsFor(shownSystem),
|
|
1239
|
+
children: calendar
|
|
1240
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
|
|
1241
|
+
value: digitsFor(draftSystem),
|
|
1242
|
+
children: timeRow
|
|
1243
|
+
}), validationMessage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_FieldMessages.default, {
|
|
883
1244
|
error: validationMessage,
|
|
884
1245
|
tokens: tokens,
|
|
885
1246
|
styles: {
|
|
@@ -889,7 +1250,8 @@ const DateTimePicker = props => {
|
|
|
889
1250
|
testID: testID ? `${testID}-validation` : undefined
|
|
890
1251
|
}) : null]
|
|
891
1252
|
});
|
|
892
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(
|
|
1253
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_numerals2.NumeralsContext.Provider, {
|
|
1254
|
+
value: digitsFor(savedSystem),
|
|
893
1255
|
children: [trigger, /*#__PURE__*/(0, _jsxRuntime.jsx)(_PickerContainer.default, {
|
|
894
1256
|
presentation: presentation,
|
|
895
1257
|
isOpen: isOpen,
|