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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { to12Hour, type SegmentError } from '../../core/segments';
|
|
2
2
|
import type { DateTimeValue, PickerType, TimeFormat } from '../../core/types';
|
|
3
3
|
import { DEFAULT_STRINGS, type PickerStrings } from '../theme/defaultStrings';
|
|
4
4
|
|
|
@@ -14,29 +14,62 @@ export const formatDateText = (
|
|
|
14
14
|
.replace('MM', pad2(value.date.month))
|
|
15
15
|
.replace('dd', pad2(value.date.day));
|
|
16
16
|
|
|
17
|
+
/** The AM / PM labels and the date-time separator, from `strings`. */
|
|
18
|
+
export type PeriodLabels = Pick<
|
|
19
|
+
PickerStrings,
|
|
20
|
+
'am' | 'pm' | 'dateTimeSeparator'
|
|
21
|
+
>;
|
|
22
|
+
|
|
17
23
|
/** '03:45 PM' (12-hour) or '15:45' (24-hour). Always shows AM/PM in 12-hour mode. */
|
|
18
24
|
export const formatTimeText = (
|
|
19
25
|
value: DateTimeValue,
|
|
20
|
-
timeFormat: TimeFormat
|
|
26
|
+
timeFormat: TimeFormat,
|
|
27
|
+
periods: PeriodLabels = DEFAULT_STRINGS
|
|
21
28
|
): string => {
|
|
22
29
|
if (!value.time) return '';
|
|
23
30
|
const { hour, minute } = value.time;
|
|
24
31
|
if (timeFormat === '24h') return `${pad2(hour)}:${pad2(minute)}`;
|
|
25
|
-
const hour12
|
|
26
|
-
return `${pad2(hour12)}:${pad2(minute)} ${
|
|
32
|
+
const { hour12, period } = to12Hour(hour);
|
|
33
|
+
return `${pad2(hour12)}:${pad2(minute)} ${period === 'AM' ? periods.am : periods.pm}`;
|
|
27
34
|
};
|
|
28
35
|
|
|
36
|
+
/** Writes a value's date some other way, e.g. as a Hijri date. */
|
|
37
|
+
export type DateTextFormatter = (value: DateTimeValue) => string;
|
|
38
|
+
|
|
39
|
+
/** A value's date and time as two texts; the time is '' for a date or a value without one. */
|
|
40
|
+
export const formatValueParts = (
|
|
41
|
+
value: DateTimeValue,
|
|
42
|
+
type: PickerType,
|
|
43
|
+
dateFormat: string,
|
|
44
|
+
timeFormat: TimeFormat,
|
|
45
|
+
dateText?: DateTextFormatter,
|
|
46
|
+
periods: PeriodLabels = DEFAULT_STRINGS
|
|
47
|
+
): { date: string; time: string } => ({
|
|
48
|
+
date: dateText ? dateText(value) : formatDateText(value, dateFormat),
|
|
49
|
+
time:
|
|
50
|
+
type === 'datetime' && value.time
|
|
51
|
+
? formatTimeText(value, timeFormat, periods)
|
|
52
|
+
: '',
|
|
53
|
+
});
|
|
54
|
+
|
|
29
55
|
export const formatValueText = (
|
|
30
56
|
value: DateTimeValue | null,
|
|
31
57
|
type: PickerType,
|
|
32
58
|
dateFormat: string,
|
|
33
|
-
timeFormat: TimeFormat
|
|
59
|
+
timeFormat: TimeFormat,
|
|
60
|
+
dateText?: DateTextFormatter,
|
|
61
|
+
periods: PeriodLabels = DEFAULT_STRINGS
|
|
34
62
|
): string => {
|
|
35
63
|
if (!value) return '';
|
|
36
|
-
const date =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
const { date, time } = formatValueParts(
|
|
65
|
+
value,
|
|
66
|
+
type,
|
|
67
|
+
dateFormat,
|
|
68
|
+
timeFormat,
|
|
69
|
+
dateText,
|
|
70
|
+
periods
|
|
71
|
+
);
|
|
72
|
+
return time ? `${date}${periods.dateTimeSeparator ?? ' '}${time}` : date;
|
|
40
73
|
};
|
|
41
74
|
|
|
42
75
|
/** '21-10-2026 – 25-10-2026'; just the start (with the dash) while the end is open. */
|
|
@@ -46,11 +79,27 @@ export const formatRangeText = (
|
|
|
46
79
|
type: PickerType,
|
|
47
80
|
dateFormat: string,
|
|
48
81
|
timeFormat: TimeFormat,
|
|
49
|
-
separator: string = ' – '
|
|
82
|
+
separator: string = ' – ',
|
|
83
|
+
dateText?: DateTextFormatter,
|
|
84
|
+
periods: PeriodLabels = DEFAULT_STRINGS
|
|
50
85
|
): string => {
|
|
51
86
|
if (!from && !to) return '';
|
|
52
|
-
const a = formatValueText(
|
|
53
|
-
|
|
87
|
+
const a = formatValueText(
|
|
88
|
+
from,
|
|
89
|
+
type,
|
|
90
|
+
dateFormat,
|
|
91
|
+
timeFormat,
|
|
92
|
+
dateText,
|
|
93
|
+
periods
|
|
94
|
+
);
|
|
95
|
+
const b = formatValueText(
|
|
96
|
+
to,
|
|
97
|
+
type,
|
|
98
|
+
dateFormat,
|
|
99
|
+
timeFormat,
|
|
100
|
+
dateText,
|
|
101
|
+
periods
|
|
102
|
+
);
|
|
54
103
|
return `${a}${separator}${b}`.trim();
|
|
55
104
|
};
|
|
56
105
|
|
|
@@ -59,11 +108,15 @@ export const formatMultipleText = (
|
|
|
59
108
|
values: (DateTimeValue | null)[],
|
|
60
109
|
type: PickerType,
|
|
61
110
|
dateFormat: string,
|
|
62
|
-
timeFormat: TimeFormat
|
|
111
|
+
timeFormat: TimeFormat,
|
|
112
|
+
dateText?: DateTextFormatter,
|
|
113
|
+
periods: PeriodLabels = DEFAULT_STRINGS
|
|
63
114
|
): string =>
|
|
64
115
|
values
|
|
65
116
|
.filter((v): v is DateTimeValue => !!v)
|
|
66
|
-
.map((v) =>
|
|
117
|
+
.map((v) =>
|
|
118
|
+
formatValueText(v, type, dateFormat, timeFormat, dateText, periods)
|
|
119
|
+
)
|
|
67
120
|
.join(', ');
|
|
68
121
|
|
|
69
122
|
/** 'DD-MM-YYYY' or 'DD-MM-YYYY hh:mm AM', from the placeholder strings. */
|
|
@@ -84,7 +137,7 @@ export const placeholderText = (
|
|
|
84
137
|
timeFormat === '24h'
|
|
85
138
|
? `${strings.placeholderHour24}:${strings.placeholderMinute}`
|
|
86
139
|
: `${strings.placeholderHour}:${strings.placeholderMinute} ${strings.am}`;
|
|
87
|
-
return `${date} ${time}`;
|
|
140
|
+
return `${date}${strings.dateTimeSeparator ?? ' '}${time}`;
|
|
88
141
|
};
|
|
89
142
|
|
|
90
143
|
const TIME_KEYS = ['hour', 'minute', 'period'];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createContext, useContext, type Context } from 'react';
|
|
2
|
+
|
|
3
|
+
type Insets = { bottom: number } | null;
|
|
4
|
+
|
|
5
|
+
declare const require: (name: string) => unknown;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* react-native-safe-area-context's insets, when the app has that package (an
|
|
9
|
+
* optional peer: most Expo apps do). The require sits in a try so a missing
|
|
10
|
+
* package is fine: Metro allows optional dependencies there.
|
|
11
|
+
*/
|
|
12
|
+
const readContext = (): Context<Insets> | null => {
|
|
13
|
+
try {
|
|
14
|
+
const lib = require('react-native-safe-area-context') as {
|
|
15
|
+
SafeAreaInsetsContext?: Context<Insets>;
|
|
16
|
+
};
|
|
17
|
+
return lib.SafeAreaInsetsContext ?? null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const NO_INSETS = createContext<Insets>(null);
|
|
24
|
+
const InsetsContext = readContext() ?? NO_INSETS;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The bottom safe-area inset (the home indicator, or Android's navigation bar
|
|
28
|
+
* in an edge-to-edge app), from the app's SafeAreaProvider; 0 without one.
|
|
29
|
+
* Read through the context rather than `useSafeAreaInsets`, which throws when
|
|
30
|
+
* there's no provider.
|
|
31
|
+
*/
|
|
32
|
+
export const useBottomInset = (): number =>
|
|
33
|
+
useContext(InsetsContext)?.bottom ?? 0;
|
|
@@ -1,31 +1,59 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import { Keyboard, Platform } from 'react-native';
|
|
2
|
+
import { Keyboard, Platform, type KeyboardEvent } from 'react-native';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
interface KeyboardState {
|
|
5
|
+
up: boolean;
|
|
6
|
+
/** The keyboard's height while it's up, 0 when down (or not reported). */
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const DOWN: KeyboardState = { up: false, height: 0 };
|
|
11
|
+
|
|
12
|
+
/** The keyboard as it is now: it can already be up when the picker mounts or opens. */
|
|
13
|
+
const current = (): KeyboardState =>
|
|
14
|
+
Keyboard.isVisible()
|
|
15
|
+
? { up: true, height: Keyboard.metrics()?.height ?? 0 }
|
|
16
|
+
: DOWN;
|
|
17
|
+
|
|
18
|
+
/** Whether the keyboard is up, and how tall it is, while `active`. */
|
|
19
|
+
export const useKeyboard = (active: boolean): KeyboardState => {
|
|
20
|
+
const [keyboard, setKeyboard] = useState(() => (active ? current() : DOWN));
|
|
12
21
|
|
|
13
22
|
useEffect(() => {
|
|
14
23
|
if (!active) {
|
|
15
|
-
|
|
24
|
+
setKeyboard(DOWN);
|
|
16
25
|
return undefined;
|
|
17
26
|
}
|
|
27
|
+
setKeyboard(current());
|
|
18
28
|
const showEvent =
|
|
19
29
|
Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
|
|
20
30
|
const hideEvent =
|
|
21
31
|
Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
|
|
22
|
-
const show = Keyboard.addListener(showEvent, () =>
|
|
23
|
-
|
|
32
|
+
const show = Keyboard.addListener(showEvent, (e?: KeyboardEvent) =>
|
|
33
|
+
setKeyboard({ up: true, height: e?.endCoordinates?.height ?? 0 })
|
|
34
|
+
);
|
|
35
|
+
const hide = Keyboard.addListener(hideEvent, () => setKeyboard(DOWN));
|
|
36
|
+
// iOS: a sheet opened on keyboardWillHide mounts before the keyboard is
|
|
37
|
+
// gone, so it reads it as up; keyboardDidHide puts that right.
|
|
38
|
+
const hidden =
|
|
39
|
+
hideEvent === 'keyboardDidHide'
|
|
40
|
+
? null
|
|
41
|
+
: Keyboard.addListener('keyboardDidHide', () => setKeyboard(DOWN));
|
|
24
42
|
return () => {
|
|
25
43
|
show.remove();
|
|
26
44
|
hide.remove();
|
|
45
|
+
hidden?.remove();
|
|
27
46
|
};
|
|
28
47
|
}, [active]);
|
|
29
48
|
|
|
30
|
-
return
|
|
49
|
+
return keyboard;
|
|
31
50
|
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* True while the keyboard is up and the picker is open. With
|
|
54
|
+
* `hideCalendarOnKeyboard` the picker folds the calendar away then, so the box being typed in (and Confirm) stay visible on
|
|
55
|
+
* small phones; inline, it folds only while one of its own boxes has focus,
|
|
56
|
+
* since another field on the screen can raise the keyboard too.
|
|
57
|
+
*/
|
|
58
|
+
export const useKeyboardFold = (active: boolean): boolean =>
|
|
59
|
+
useKeyboard(active).up;
|
|
@@ -19,7 +19,8 @@ interface Options {
|
|
|
19
19
|
* Opens and closes the picker.
|
|
20
20
|
* - calls `onBeforeOpen` first;
|
|
21
21
|
* - if a text input has focus, closes the keyboard and waits for it on iOS and
|
|
22
|
-
* Android (so the sheet doesn't jump as the keyboard leaves), with a 450 ms
|
|
22
|
+
* Android (so the sheet doesn't jump as the keyboard leaves), with a 450 ms
|
|
23
|
+
* fallback; a controlled `visible` turned on waits the same way;
|
|
23
24
|
* - disabled and read-only pickers never open.
|
|
24
25
|
*/
|
|
25
26
|
export const useOpenPicker = ({
|
|
@@ -32,7 +33,16 @@ export const useOpenPicker = ({
|
|
|
32
33
|
}: Options): { isOpen: boolean; open: () => void; close: () => void } => {
|
|
33
34
|
const [openState, setOpenState] = useState(false);
|
|
34
35
|
const isControlled = visible !== undefined;
|
|
35
|
-
|
|
36
|
+
// Controlled: `visible` turned on while a text input has focus waits for
|
|
37
|
+
// the keyboard. Decided while rendering, so the sheet never shows a frame
|
|
38
|
+
// early.
|
|
39
|
+
const [keyboardWait, setKeyboardWait] = useState(false);
|
|
40
|
+
const [seenVisible, setSeenVisible] = useState(visible);
|
|
41
|
+
if (isControlled && visible !== seenVisible) {
|
|
42
|
+
setSeenVisible(visible);
|
|
43
|
+
setKeyboardWait(!!visible && !!TextInput.State.currentlyFocusedInput?.());
|
|
44
|
+
}
|
|
45
|
+
const isOpen = isControlled ? !!visible && !keyboardWait : openState;
|
|
36
46
|
const pending = useRef<{ cancel: () => void } | null>(null);
|
|
37
47
|
|
|
38
48
|
const cancelPending = () => {
|
|
@@ -41,29 +51,17 @@ export const useOpenPicker = ({
|
|
|
41
51
|
};
|
|
42
52
|
useEffect(() => cancelPending, []);
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (!isControlled) setOpenState(true);
|
|
47
|
-
onOpen?.();
|
|
48
|
-
}, [isControlled, onOpen]);
|
|
49
|
-
|
|
50
|
-
const open = useCallback(() => {
|
|
51
|
-
if (disabled || readOnly || isOpen || pending.current) return;
|
|
52
|
-
onBeforeOpen?.();
|
|
53
|
-
const focused = TextInput.State.currentlyFocusedInput?.();
|
|
54
|
-
if (!focused) {
|
|
55
|
-
reallyOpen();
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
54
|
+
/** Closes the keyboard and calls `then` once it's gone (or after the fallback). */
|
|
55
|
+
const afterKeyboard = (then: () => void) => {
|
|
58
56
|
const event =
|
|
59
57
|
Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
|
|
60
58
|
const sub = Keyboard.addListener(event, () => {
|
|
61
59
|
cancelPending();
|
|
62
|
-
|
|
60
|
+
then();
|
|
63
61
|
});
|
|
64
62
|
const timer = setTimeout(() => {
|
|
65
63
|
cancelPending();
|
|
66
|
-
|
|
64
|
+
then();
|
|
67
65
|
}, KEYBOARD_WAIT_FALLBACK_MS);
|
|
68
66
|
pending.current = {
|
|
69
67
|
cancel: () => {
|
|
@@ -72,6 +70,31 @@ export const useOpenPicker = ({
|
|
|
72
70
|
},
|
|
73
71
|
};
|
|
74
72
|
Keyboard.dismiss();
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!keyboardWait) return undefined;
|
|
77
|
+
afterKeyboard(() => setKeyboardWait(false));
|
|
78
|
+
return cancelPending;
|
|
79
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- while waiting
|
|
80
|
+
}, [keyboardWait]);
|
|
81
|
+
|
|
82
|
+
const reallyOpen = useCallback(() => {
|
|
83
|
+
pending.current = null;
|
|
84
|
+
if (!isControlled) setOpenState(true);
|
|
85
|
+
onOpen?.();
|
|
86
|
+
}, [isControlled, onOpen]);
|
|
87
|
+
|
|
88
|
+
const open = useCallback(() => {
|
|
89
|
+
if (disabled || readOnly || isOpen || pending.current) return;
|
|
90
|
+
onBeforeOpen?.();
|
|
91
|
+
const focused = TextInput.State.currentlyFocusedInput?.();
|
|
92
|
+
if (!focused) {
|
|
93
|
+
reallyOpen();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
afterKeyboard(reallyOpen);
|
|
97
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- afterKeyboard only uses refs and stable APIs
|
|
75
98
|
}, [disabled, readOnly, isOpen, onBeforeOpen, reallyOpen]);
|
|
76
99
|
|
|
77
100
|
const close = useCallback(() => {
|
|
@@ -17,12 +17,13 @@ const valueKey = (v: DateTimeValue | null): string =>
|
|
|
17
17
|
/**
|
|
18
18
|
* State for the typed field. Re-syncs from `value` when it changes from outside
|
|
19
19
|
* (a calendar tap, a clear) while no segment is focused, and reports every
|
|
20
|
-
* parse result to `onParsed
|
|
20
|
+
* parse result to `onParsed`, saying whether it came from such a value
|
|
21
|
+
* (`fromOutside`) rather than from typing.
|
|
21
22
|
*/
|
|
22
23
|
export const useTypedSegments = (
|
|
23
24
|
value: DateTimeValue | null,
|
|
24
25
|
options: SegmentEditorOptions,
|
|
25
|
-
onParsed?: (parsed: ParsedSegments) => void
|
|
26
|
+
onParsed?: (parsed: ParsedSegments, fromOutside: boolean) => void
|
|
26
27
|
): {
|
|
27
28
|
state: SegmentEditorState;
|
|
28
29
|
dispatch: (action: SegmentEditorAction) => void;
|
|
@@ -51,9 +52,12 @@ export const useTypedSegments = (
|
|
|
51
52
|
// Fast typing (a hardware keyboard, autofill) sends the next character
|
|
52
53
|
// before React re-renders, so inputs compare against this, not `state`.
|
|
53
54
|
const latest = useRef(state);
|
|
55
|
+
// Whether the last action was a value set from outside, not typing.
|
|
56
|
+
const lastWasReset = useRef(false);
|
|
54
57
|
const dispatch = useCallback(
|
|
55
58
|
(action: SegmentEditorAction) => {
|
|
56
59
|
latest.current = reducer(latest.current, action);
|
|
60
|
+
lastWasReset.current = action.type === 'reset';
|
|
57
61
|
reactDispatch(action);
|
|
58
62
|
},
|
|
59
63
|
[reducer]
|
|
@@ -93,7 +97,7 @@ export const useTypedSegments = (
|
|
|
93
97
|
// What's typed is newer than anything that was waiting to be shown.
|
|
94
98
|
resetOnLeave.current = false;
|
|
95
99
|
}
|
|
96
|
-
onParsedRef.current?.(state.parsed);
|
|
100
|
+
onParsedRef.current?.(state.parsed, lastWasReset.current);
|
|
97
101
|
}, [state.parsed]);
|
|
98
102
|
|
|
99
103
|
return { state, dispatch, getState };
|
|
@@ -18,6 +18,8 @@ export interface PickerStrings {
|
|
|
18
18
|
/** Between the two ends of a range in the field text. */
|
|
19
19
|
rangeSeparator: string;
|
|
20
20
|
pm: string;
|
|
21
|
+
/** Between the date and the time in the field text and its placeholder. */
|
|
22
|
+
dateTimeSeparator?: string;
|
|
21
23
|
/** Placeholders of the typed date segments and time boxes, and of the empty field. */
|
|
22
24
|
placeholderDay: string;
|
|
23
25
|
placeholderMonth: string;
|
|
@@ -39,8 +41,15 @@ export interface PickerStrings {
|
|
|
39
41
|
errorRangeTooShort: (days: number) => string;
|
|
40
42
|
errorRangeTooLong: (days: number) => string;
|
|
41
43
|
nothingSelectable: string;
|
|
44
|
+
/** The calendar switch and the dual tabs. */
|
|
45
|
+
calendarGregorian?: string;
|
|
46
|
+
calendarHijri?: string;
|
|
47
|
+
calendarDual?: string;
|
|
48
|
+
a11yCalendarSystem?: string;
|
|
42
49
|
a11yClear: string;
|
|
43
50
|
a11yOpen: string;
|
|
51
|
+
/** The built-in sheet's backdrop, which closes it. */
|
|
52
|
+
a11yClose?: string;
|
|
44
53
|
a11yDay: string;
|
|
45
54
|
a11yMonth: string;
|
|
46
55
|
a11yYear: string;
|
|
@@ -57,7 +66,7 @@ export interface PickerStrings {
|
|
|
57
66
|
a11yRangeEnd: string;
|
|
58
67
|
}
|
|
59
68
|
|
|
60
|
-
export const DEFAULT_STRINGS: PickerStrings = {
|
|
69
|
+
export const DEFAULT_STRINGS: Required<PickerStrings> = {
|
|
61
70
|
titleDate: 'Select date',
|
|
62
71
|
confirm: 'Confirm',
|
|
63
72
|
reset: 'Reset',
|
|
@@ -72,6 +81,7 @@ export const DEFAULT_STRINGS: PickerStrings = {
|
|
|
72
81
|
am: 'AM',
|
|
73
82
|
rangeSeparator: ' – ',
|
|
74
83
|
pm: 'PM',
|
|
84
|
+
dateTimeSeparator: ' ',
|
|
75
85
|
placeholderDay: 'DD',
|
|
76
86
|
placeholderMonth: 'MM',
|
|
77
87
|
placeholderYear: 'YYYY',
|
|
@@ -87,12 +97,17 @@ export const DEFAULT_STRINGS: PickerStrings = {
|
|
|
87
97
|
errorNotAllowed: "This date isn't available",
|
|
88
98
|
errorTimeNotAllowed: "This time isn't available",
|
|
89
99
|
errorMinuteStep: (step) => `Choose a minute in steps of ${step}`,
|
|
90
|
-
errorRangeOrder: 'The end must be
|
|
100
|
+
errorRangeOrder: 'The end date must be greater than the start date',
|
|
91
101
|
errorRangeTooShort: (n) => `Choose a range of at least ${n} days`,
|
|
92
102
|
errorRangeTooLong: (n) => `Choose a range of at most ${n} days`,
|
|
93
103
|
nothingSelectable: 'No dates are available',
|
|
104
|
+
calendarGregorian: 'Gregorian',
|
|
105
|
+
calendarHijri: 'Hijri',
|
|
106
|
+
calendarDual: 'Dual',
|
|
107
|
+
a11yCalendarSystem: 'Calendar',
|
|
94
108
|
a11yClear: 'Clear date',
|
|
95
109
|
a11yOpen: 'Open date picker',
|
|
110
|
+
a11yClose: 'Close',
|
|
96
111
|
a11yDay: 'Day',
|
|
97
112
|
a11yMonth: 'Month',
|
|
98
113
|
a11yYear: 'Year',
|
|
@@ -109,9 +124,19 @@ export const DEFAULT_STRINGS: PickerStrings = {
|
|
|
109
124
|
a11yRangeEnd: 'end of range',
|
|
110
125
|
};
|
|
111
126
|
|
|
127
|
+
/** The keys that have a value: one left `undefined` (or `null`) keeps what's under it. */
|
|
128
|
+
export const compactStrings = (
|
|
129
|
+
overrides?: Partial<PickerStrings>
|
|
130
|
+
): Partial<PickerStrings> =>
|
|
131
|
+
overrides
|
|
132
|
+
? (Object.fromEntries(
|
|
133
|
+
Object.entries(overrides).filter(([, v]) => v != null)
|
|
134
|
+
) as Partial<PickerStrings>)
|
|
135
|
+
: {};
|
|
136
|
+
|
|
112
137
|
/** The English defaults with the caller's overrides on top. */
|
|
113
138
|
export const resolveStrings = (
|
|
114
139
|
overrides?: Partial<PickerStrings>
|
|
115
|
-
): PickerStrings => {
|
|
116
|
-
return { ...DEFAULT_STRINGS, ...overrides };
|
|
140
|
+
): Required<PickerStrings> => {
|
|
141
|
+
return { ...DEFAULT_STRINGS, ...compactStrings(overrides) };
|
|
117
142
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { I18nManager } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether a part of the picker is laid out right to left. The picker sets it
|
|
6
|
+
* for the calendar and the time rows while the Hijri tab shows; elsewhere the
|
|
7
|
+
* app's direction (`I18nManager.isRTL`) decides.
|
|
8
|
+
*/
|
|
9
|
+
export const RtlContext = createContext<boolean | null>(null);
|
|
10
|
+
|
|
11
|
+
export const useIsRTL = (): boolean =>
|
|
12
|
+
useContext(RtlContext) ?? I18nManager.isRTL;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { latinDigits } from '../../core/numerals';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The digits every number in the picker is drawn with, set once by the picker
|
|
6
|
+
* from its `numerals` and `locale` props. Values and typed input stay 0–9.
|
|
7
|
+
*/
|
|
8
|
+
export const NumeralsContext =
|
|
9
|
+
createContext<(text: string) => string>(latinDigits);
|
|
10
|
+
|
|
11
|
+
export const useNumerals = () => useContext(NumeralsContext);
|
|
@@ -25,6 +25,11 @@ export const STYLE_KEYS = [
|
|
|
25
25
|
'fieldText',
|
|
26
26
|
/** The value's text while the field is disabled (the placeholder keeps its own colour). */
|
|
27
27
|
'fieldTextDisabled',
|
|
28
|
+
/**
|
|
29
|
+
* Sets the date of a single date-time value apart from its time, e.g.
|
|
30
|
+
* `{ minWidth: '50%' }` starts the time at the middle of the field.
|
|
31
|
+
*/
|
|
32
|
+
'fieldDateText',
|
|
28
33
|
'fieldPlaceholder',
|
|
29
34
|
'fieldSegment',
|
|
30
35
|
'fieldSegmentFocused',
|
|
@@ -52,6 +57,18 @@ export const STYLE_KEYS = [
|
|
|
52
57
|
'monthChipText',
|
|
53
58
|
'monthChipSelected',
|
|
54
59
|
'monthChipDisabled',
|
|
60
|
+
// calendar switch (calendarSwitch prop)
|
|
61
|
+
'calendarSwitch',
|
|
62
|
+
'calendarSwitchSegment',
|
|
63
|
+
'calendarSwitchSegmentSelected',
|
|
64
|
+
'calendarSwitchText',
|
|
65
|
+
'calendarSwitchTextSelected',
|
|
66
|
+
/** The Gregorian / Hijri tabs of a dual calendar. */
|
|
67
|
+
'dualTabs',
|
|
68
|
+
'dualTab',
|
|
69
|
+
'dualTabSelected',
|
|
70
|
+
'dualTabText',
|
|
71
|
+
'dualTabTextSelected',
|
|
55
72
|
// weekdays
|
|
56
73
|
'weekdayRow',
|
|
57
74
|
'weekdayText',
|
|
@@ -73,7 +90,7 @@ export const STYLE_KEYS = [
|
|
|
73
90
|
'disabledText',
|
|
74
91
|
'holiday',
|
|
75
92
|
'holidayText',
|
|
76
|
-
/**
|
|
93
|
+
/** A second line under the day number. Not drawn by the picker any more; kept so styles that set it still compile. */
|
|
77
94
|
'daySubLabel',
|
|
78
95
|
// grids
|
|
79
96
|
'yearGrid',
|
|
@@ -9,6 +9,8 @@ export interface ThemeTokens {
|
|
|
9
9
|
/** Headings in the sheet: the year title and the time label. */
|
|
10
10
|
heading: string;
|
|
11
11
|
mutedText: string;
|
|
12
|
+
/** Days of the months before and after, which can still be picked. */
|
|
13
|
+
outsideText?: string;
|
|
12
14
|
placeholder: string;
|
|
13
15
|
border: string;
|
|
14
16
|
/** Typed time boxes. */
|
|
@@ -46,12 +48,13 @@ export interface ThemeTokens {
|
|
|
46
48
|
touchTarget: number;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
export const DEFAULT_TOKENS: ThemeTokens = {
|
|
51
|
+
export const DEFAULT_TOKENS: Required<ThemeTokens> = {
|
|
50
52
|
accent: '#2563EB',
|
|
51
53
|
onAccent: '#FFFFFF',
|
|
52
54
|
text: '#111827',
|
|
53
55
|
heading: '#111827',
|
|
54
56
|
mutedText: '#6B7280',
|
|
57
|
+
outsideText: '#6B7280',
|
|
55
58
|
placeholder: '#9CA3AF',
|
|
56
59
|
border: '#D1D5DB',
|
|
57
60
|
inputBorder: '#D1D5DB',
|
|
@@ -109,6 +112,7 @@ export const buildTokens = (overrides?: Partial<ThemeTokens>): ThemeTokens => {
|
|
|
109
112
|
return {
|
|
110
113
|
...DEFAULT_TOKENS,
|
|
111
114
|
...(overrides?.accent ? { borderFocused: overrides.accent } : null),
|
|
115
|
+
...(overrides?.mutedText ? { outsideText: overrides.mutedText } : null),
|
|
112
116
|
...overrides,
|
|
113
117
|
};
|
|
114
118
|
};
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import { Text, View } from 'react-native';
|
|
3
9
|
import type { TextInputRef } from '../nativeTypes';
|
|
4
10
|
import type { TimeBounds } from '../../core/constraints';
|
|
@@ -244,6 +250,20 @@ const TimeRow: React.FC<TimeRowProps> = ({
|
|
|
244
250
|
const setRef = useCallback((key: TimeKey, r: TextInputRef | null) => {
|
|
245
251
|
refs.current[key] = r;
|
|
246
252
|
}, []);
|
|
253
|
+
// 'Start time, Hour' and 'End time, Hour' read differently, as the typed
|
|
254
|
+
// date field's segments do.
|
|
255
|
+
const boxStrings = useMemo(
|
|
256
|
+
() =>
|
|
257
|
+
label
|
|
258
|
+
? {
|
|
259
|
+
...strings,
|
|
260
|
+
a11yHour: `${label}, ${strings.a11yHour}`,
|
|
261
|
+
a11yMinute: `${label}, ${strings.a11yMinute}`,
|
|
262
|
+
a11yPeriod: `${label}, ${strings.a11yPeriod}`,
|
|
263
|
+
}
|
|
264
|
+
: strings,
|
|
265
|
+
[label, strings]
|
|
266
|
+
);
|
|
247
267
|
|
|
248
268
|
return (
|
|
249
269
|
<View style={s.wrapper} testID={testID}>
|
|
@@ -263,7 +283,7 @@ const TimeRow: React.FC<TimeRowProps> = ({
|
|
|
263
283
|
disabled={disabled}
|
|
264
284
|
tokens={tokens}
|
|
265
285
|
styles={styles}
|
|
266
|
-
strings={
|
|
286
|
+
strings={boxStrings}
|
|
267
287
|
testID={testID ? `${testID}-wheel` : undefined}
|
|
268
288
|
/>
|
|
269
289
|
) : (
|
|
@@ -282,7 +302,7 @@ const TimeRow: React.FC<TimeRowProps> = ({
|
|
|
282
302
|
disabled={disabled}
|
|
283
303
|
tokens={tokens}
|
|
284
304
|
styles={styles}
|
|
285
|
-
strings={
|
|
305
|
+
strings={boxStrings}
|
|
286
306
|
testID={testID}
|
|
287
307
|
/>
|
|
288
308
|
)}
|
|
@@ -12,6 +12,7 @@ import type { TimeFormat } from '../../core/types';
|
|
|
12
12
|
import type { PickerStrings } from '../theme/defaultStrings';
|
|
13
13
|
import type { PickerStyles } from '../theme/styleKeys';
|
|
14
14
|
import { MAX_FONT_SCALE } from '../theme/a11y';
|
|
15
|
+
import { useNumerals } from '../theme/numerals';
|
|
15
16
|
import type { ThemeTokens } from '../theme/tokens';
|
|
16
17
|
import { buildTimeStyles } from './timeStyles';
|
|
17
18
|
|
|
@@ -59,6 +60,7 @@ const TypedTime: React.FC<Props> = ({
|
|
|
59
60
|
strings,
|
|
60
61
|
testID,
|
|
61
62
|
}) => {
|
|
63
|
+
const digits = useNumerals();
|
|
62
64
|
const s = buildTimeStyles(tokens);
|
|
63
65
|
|
|
64
66
|
const box = (key: TimeKey) => (
|
|
@@ -78,7 +80,7 @@ const TypedTime: React.FC<Props> = ({
|
|
|
78
80
|
accessibilityLabel={
|
|
79
81
|
key === 'hour' ? strings.a11yHour : strings.a11yMinute
|
|
80
82
|
}
|
|
81
|
-
value={values[key] ?? ''}
|
|
83
|
+
value={digits(values[key] ?? '')}
|
|
82
84
|
placeholder={
|
|
83
85
|
key === 'minute'
|
|
84
86
|
? strings.placeholderMinute
|