rn-grid-date-time-picker 1.3.0 → 1.3.1

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/lib/commonjs/components/DateTimePicker.js +67 -115
  3. package/lib/commonjs/components/DateTimePicker.js.map +1 -1
  4. package/lib/commonjs/components/calendar/DayCell.js +17 -6
  5. package/lib/commonjs/components/calendar/DayCell.js.map +1 -1
  6. package/lib/commonjs/components/calendar/calendarStyles.js +11 -0
  7. package/lib/commonjs/components/calendar/calendarStyles.js.map +1 -1
  8. package/lib/commonjs/components/field/ValueField.js +19 -2
  9. package/lib/commonjs/components/field/ValueField.js.map +1 -1
  10. package/lib/commonjs/components/field/fieldText.js +44 -5
  11. package/lib/commonjs/components/field/fieldText.js.map +1 -1
  12. package/lib/commonjs/components/theme/styleKeys.js +3 -1
  13. package/lib/commonjs/components/theme/styleKeys.js.map +1 -1
  14. package/lib/commonjs/components/types.js +2 -1
  15. package/lib/commonjs/components/types.js.map +1 -1
  16. package/lib/module/components/DateTimePicker.js +68 -116
  17. package/lib/module/components/DateTimePicker.js.map +1 -1
  18. package/lib/module/components/calendar/DayCell.js +18 -7
  19. package/lib/module/components/calendar/DayCell.js.map +1 -1
  20. package/lib/module/components/calendar/calendarStyles.js +11 -0
  21. package/lib/module/components/calendar/calendarStyles.js.map +1 -1
  22. package/lib/module/components/field/ValueField.js +20 -3
  23. package/lib/module/components/field/ValueField.js.map +1 -1
  24. package/lib/module/components/field/fieldText.js +40 -4
  25. package/lib/module/components/field/fieldText.js.map +1 -1
  26. package/lib/module/components/theme/styleKeys.js +3 -1
  27. package/lib/module/components/theme/styleKeys.js.map +1 -1
  28. package/lib/module/components/types.js +2 -1
  29. package/lib/module/components/types.js.map +1 -1
  30. package/lib/typescript/commonjs/src/components/DateTimePicker.d.ts.map +1 -1
  31. package/lib/typescript/commonjs/src/components/calendar/DayCell.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts +9 -0
  33. package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/src/components/field/ValueField.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/src/components/field/fieldText.d.ts +19 -0
  36. package/lib/typescript/commonjs/src/components/field/fieldText.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/src/components/theme/styleKeys.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/src/components/types.d.ts +18 -5
  39. package/lib/typescript/commonjs/src/components/types.d.ts.map +1 -1
  40. package/lib/typescript/module/src/components/DateTimePicker.d.ts.map +1 -1
  41. package/lib/typescript/module/src/components/calendar/DayCell.d.ts.map +1 -1
  42. package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts +9 -0
  43. package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts.map +1 -1
  44. package/lib/typescript/module/src/components/field/ValueField.d.ts.map +1 -1
  45. package/lib/typescript/module/src/components/field/fieldText.d.ts +19 -0
  46. package/lib/typescript/module/src/components/field/fieldText.d.ts.map +1 -1
  47. package/lib/typescript/module/src/components/theme/styleKeys.d.ts.map +1 -1
  48. package/lib/typescript/module/src/components/types.d.ts +18 -5
  49. package/lib/typescript/module/src/components/types.d.ts.map +1 -1
  50. package/package.json +1 -1
  51. package/src/components/DateTimePicker.tsx +79 -120
  52. package/src/components/calendar/DayCell.tsx +25 -6
  53. package/src/components/calendar/calendarStyles.ts +11 -0
  54. package/src/components/field/ValueField.tsx +30 -11
  55. package/src/components/field/fieldText.ts +48 -5
  56. package/src/components/theme/styleKeys.ts +3 -1
  57. package/src/components/types.ts +18 -5
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.segmentErrorText = exports.placeholderText = exports.formatValueText = exports.formatValueParts = exports.formatTimeText = exports.formatRangeText = exports.formatMultipleText = exports.formatDateText = void 0;
6
+ exports.splitPlaceholder = exports.segmentErrorText = exports.placeholderText = exports.placeholderParts = exports.formatValueText = exports.formatValueParts = exports.formatTimeText = exports.formatRangeText = exports.formatMultipleText = exports.formatDateText = exports.emptyFieldParts = void 0;
7
7
  var _segments = require("../../core/segments.js");
8
8
  var _defaultStrings = require("../theme/defaultStrings.js");
9
9
  const pad2 = n => String(n).padStart(2, '0');
@@ -58,20 +58,59 @@ const formatRangeText = (from, to, type, dateFormat, timeFormat, separator = '
58
58
  exports.formatRangeText = formatRangeText;
59
59
  const formatMultipleText = (values, type, dateFormat, timeFormat, dateText, periods = _defaultStrings.DEFAULT_STRINGS) => values.filter(v => !!v).map(v => formatValueText(v, type, dateFormat, timeFormat, dateText, periods)).join(', ');
60
60
 
61
- /** 'DD-MM-YYYY' or 'DD-MM-YYYY hh:mm AM', from the placeholder strings. */
61
+ /** { date: 'DD-MM-YYYY', time: 'hh:mm AM' } (time '' unless datetime), from the placeholder strings. */
62
62
  exports.formatMultipleText = formatMultipleText;
63
- const placeholderText = (type, dateFormat, timeFormat, strings = _defaultStrings.DEFAULT_STRINGS) => {
63
+ const placeholderParts = (type, dateFormat, timeFormat, strings = _defaultStrings.DEFAULT_STRINGS) => {
64
64
  const parts = {
65
65
  dd: strings.placeholderDay,
66
66
  MM: strings.placeholderMonth,
67
67
  yyyy: strings.placeholderYear
68
68
  };
69
69
  const date = dateFormat.replace(/yyyy|MM|dd/g, t => parts[t] ?? t);
70
- if (type !== 'datetime') return date;
70
+ if (type !== 'datetime') return {
71
+ date,
72
+ time: ''
73
+ };
71
74
  const time = timeFormat === '24h' ? `${strings.placeholderHour24}:${strings.placeholderMinute}` : `${strings.placeholderHour}:${strings.placeholderMinute} ${strings.am}`;
72
- return `${date}${strings.dateTimeSeparator ?? ' '}${time}`;
75
+ return {
76
+ date,
77
+ time
78
+ };
79
+ };
80
+
81
+ /** 'DD-MM-YYYY' or 'DD-MM-YYYY hh:mm AM', from the placeholder strings. */
82
+ exports.placeholderParts = placeholderParts;
83
+ const placeholderText = (type, dateFormat, timeFormat, strings = _defaultStrings.DEFAULT_STRINGS) => {
84
+ const {
85
+ date,
86
+ time
87
+ } = placeholderParts(type, dateFormat, timeFormat, strings);
88
+ return time ? `${date}${strings.dateTimeSeparator ?? ' '}${time}` : date;
73
89
  };
90
+
91
+ /**
92
+ * A placeholder passed in, cut at the first date-time separator into the
93
+ * date and the time ('DD/MM/YYYY HH:MM' -> 'DD/MM/YYYY', 'HH:MM'). Text
94
+ * whose second part isn't a time (no ':'), like 'Pick a time', stays whole.
95
+ */
74
96
  exports.placeholderText = placeholderText;
97
+ const splitPlaceholder = (text, separator) => {
98
+ const at = separator ? text.indexOf(separator) : -1;
99
+ const time = at > 0 ? text.slice(at + separator.length) : '';
100
+ if (!time.includes(':')) return {
101
+ date: text,
102
+ time: ''
103
+ };
104
+ return {
105
+ date: text.slice(0, at),
106
+ time
107
+ };
108
+ };
109
+
110
+ /** The empty field's placeholder (the one passed in, else the built one) as date and time. */
111
+ exports.splitPlaceholder = splitPlaceholder;
112
+ const emptyFieldParts = (placeholder, type, dateFormat, timeFormat, strings = _defaultStrings.DEFAULT_STRINGS) => placeholder ? splitPlaceholder(placeholder, strings.dateTimeSeparator ?? ' ') : placeholderParts(type, dateFormat, timeFormat, strings);
113
+ exports.emptyFieldParts = emptyFieldParts;
75
114
  const TIME_KEYS = ['hour', 'minute', 'period'];
76
115
 
77
116
  /** The message shown below the field for the first typed-input problem. */
@@ -1 +1 @@
1
- {"version":3,"names":["_segments","require","_defaultStrings","pad2","n","String","padStart","formatDateText","value","dateFormat","replace","date","year","month","day","exports","formatTimeText","timeFormat","periods","DEFAULT_STRINGS","time","hour","minute","hour12","period","to12Hour","am","pm","formatValueParts","type","dateText","formatValueText","dateTimeSeparator","formatRangeText","from","to","separator","a","b","trim","formatMultipleText","values","filter","v","map","join","placeholderText","strings","parts","dd","placeholderDay","MM","placeholderMonth","yyyy","placeholderYear","t","placeholderHour24","placeholderMinute","placeholderHour","TIME_KEYS","segmentErrorText","errors","yearRange","first","isTime","includes","key","code","errorIncompleteTime","errorIncomplete","errorInvalidTime","errorInvalidDate","errorYearOutOfRange"],"sourceRoot":"../../../../src","sources":["components/field/fieldText.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_segments","require","_defaultStrings","pad2","n","String","padStart","formatDateText","value","dateFormat","replace","date","year","month","day","exports","formatTimeText","timeFormat","periods","DEFAULT_STRINGS","time","hour","minute","hour12","period","to12Hour","am","pm","formatValueParts","type","dateText","formatValueText","dateTimeSeparator","formatRangeText","from","to","separator","a","b","trim","formatMultipleText","values","filter","v","map","join","placeholderParts","strings","parts","dd","placeholderDay","MM","placeholderMonth","yyyy","placeholderYear","t","placeholderHour24","placeholderMinute","placeholderHour","placeholderText","splitPlaceholder","text","at","indexOf","slice","length","includes","emptyFieldParts","placeholder","TIME_KEYS","segmentErrorText","errors","yearRange","first","isTime","key","code","errorIncompleteTime","errorIncomplete","errorInvalidTime","errorInvalidDate","errorYearOutOfRange"],"sourceRoot":"../../../../src","sources":["components/field/fieldText.ts"],"mappings":"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","ignoreList":[]}
@@ -16,7 +16,9 @@ const STYLE_KEYS = exports.STYLE_KEYS = [
16
16
  'fieldTextDisabled',
17
17
  /**
18
18
  * Sets the date of a single date-time value apart from its time, e.g.
19
- * `{ minWidth: '50%' }` starts the time at the middle of the field.
19
+ * `{ minWidth: '50%' }` starts the time at the middle of the field. The empty
20
+ * field's placeholder does the same: a passed `placeholder` is cut at the
21
+ * first `strings.dateTimeSeparator` when what follows is a time ('HH:MM').
20
22
  */
21
23
  'fieldDateText', 'fieldPlaceholder', 'fieldSegment', 'fieldSegmentFocused', 'fieldSeparator', 'fieldPeriod', 'fieldPeriodSelected', 'fieldPeriodText', 'fieldIcon', 'clearIcon', 'label', 'mandatoryMark', 'helperText', 'instructionText', 'errorText', /** The `validate` message inside the picker (on top of `errorText`). */
22
24
  'validationText',
@@ -1 +1 @@
1
- {"version":3,"names":["STYLE_KEYS","exports"],"sourceRoot":"../../../../src","sources":["components/theme/styleKeys.ts"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACO,MAAMA,UAAU,GAAAC,OAAA,CAAAD,UAAA,GAAG;AACxB;AACA,WAAW,EACX,OAAO,EACP,eAAe,EACf,QAAQ,EACR,OAAO,EACP,aAAa,EACb,WAAW,EACX,MAAM,EACN,QAAQ,EACR,eAAe,EACf,aAAa;AACb;AACA,OAAO,EACP,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX;AACA,mBAAmB;AACnB;AACF;AACA;AACA;AACE,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,OAAO,EACP,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX;AACA,gBAAgB;AAChB;AACA,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,mBAAmB;AACnB;AACA,gBAAgB,EAChB,uBAAuB,EACvB,+BAA+B,EAC/B,oBAAoB,EACpB,4BAA4B,EAC5B;AACA,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,qBAAqB;AACrB;AACA,YAAY,EACZ,aAAa;AACb;AACA,KAAK,EACL,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,UAAU,EACV,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb;AACA,aAAa;AACb;AACA,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd;AACA,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf;AACA,kBAAkB;AAClB;AACA,SAAS,EACT,WAAW,EACX;AACA,eAAe,EACf;AACA,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB;AAChB;AACA,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,CACR;;AAMV","ignoreList":[]}
1
+ {"version":3,"names":["STYLE_KEYS","exports"],"sourceRoot":"../../../../src","sources":["components/theme/styleKeys.ts"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACO,MAAMA,UAAU,GAAAC,OAAA,CAAAD,UAAA,GAAG;AACxB;AACA,WAAW,EACX,OAAO,EACP,eAAe,EACf,QAAQ,EACR,OAAO,EACP,aAAa,EACb,WAAW,EACX,MAAM,EACN,QAAQ,EACR,eAAe,EACf,aAAa;AACb;AACA,OAAO,EACP,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX;AACA,mBAAmB;AACnB;AACF;AACA;AACA;AACA;AACA;AACE,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,OAAO,EACP,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX;AACA,gBAAgB;AAChB;AACA,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,mBAAmB;AACnB;AACA,gBAAgB,EAChB,uBAAuB,EACvB,+BAA+B,EAC/B,oBAAoB,EACpB,4BAA4B,EAC5B;AACA,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,qBAAqB;AACrB;AACA,YAAY,EACZ,aAAa;AACb;AACA,KAAK,EACL,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,UAAU,EACV,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb;AACA,aAAa;AACb;AACA,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd;AACA,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf;AACA,kBAAkB;AAClB;AACA,SAAS,EACT,WAAW,EACX;AACA,eAAe,EACf;AACA,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB;AAChB;AACA,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,CACR;;AAMV","ignoreList":[]}
@@ -31,7 +31,8 @@ exports.DEFAULT_YEAR_RANGE = void 0;
31
31
 
32
32
  /**
33
33
  * The second argument of `onChange` when the picker can show a Hijri calendar:
34
- * the calendar the date was picked in. The value itself is always Gregorian.
34
+ * the calendar the date was picked in, which is the tab on screen when it was
35
+ * saved. The value itself is always Gregorian.
35
36
  * The picker remembers it while mounted; to show a stored value back the same
36
37
  * way later, store this too and pass it as `dualDefaultTab` (dual) or
37
38
  * `calendarSystem`.
@@ -1 +1 @@
1
- {"version":3,"names":["DEFAULT_YEAR_RANGE","exports","first","last"],"sourceRoot":"../../../src","sources":["components/types.ts"],"mappings":";;;;;;AAuBA;AACA;AACA;AACA;AACA;;AAEA;;AA0CA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAWA;;AAQA;;AAGA;;AAiDA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;;AAUA;;AAYA;;AAcA;;AAOA;;AA6QO,MAAMA,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,GAAG;EAAEE,KAAK,EAAE,IAAI;EAAEC,IAAI,EAAE;AAAK,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["DEFAULT_YEAR_RANGE","exports","first","last"],"sourceRoot":"../../../src","sources":["components/types.ts"],"mappings":";;;;;;AAuBA;AACA;AACA;AACA;AACA;;AAEA;;AA0CA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAWA;;AAQA;;AAGA;;AAwDA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;;AAUA;;AAYA;;AAcA;;AAOA;;AAkRO,MAAMA,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,GAAG;EAAEE,KAAK,EAAE,IAAI;EAAEC,IAAI,EAAE;AAAK,CAAC","ignoreList":[]}
@@ -6,7 +6,7 @@ import { View } from 'react-native';
6
6
  import { resolveAdapter } from "../adapters/index.js";
7
7
  import { compareCalendarDates, daysBetween, isSameDay } from "../core/calendarDate.js";
8
8
  import { createConstraints } from "../core/constraints.js";
9
- import { clearDraft as emptied, createDraft, DEFAULT_TIME, draftToWire, sameDayRangeOk, setTime as applyTime, validateDraft } from "../core/draft.js";
9
+ import { createDraft, DEFAULT_TIME, draftToWire, sameDayRangeOk, setTime as applyTime, validateDraft } from "../core/draft.js";
10
10
  import { hijriDateText, hijriPeriods, isHijriSupported, resolveCalendarSystem } from "../core/calendarSystem.js";
11
11
  import { defaultLocale, deriveDateFormat, deriveFirstDayOfWeek, deriveTimeFormat, normalizeDateFormat } from "../core/locale.js";
12
12
  import { arabicDigits, latinDigits, localeDigits } from "../core/numerals.js";
@@ -17,7 +17,6 @@ import CalendarSwitch from "./calendar/CalendarSwitch.js";
17
17
  import { localeNames } from "./calendar/localeNames.js";
18
18
  import { RtlContext } from "./theme/direction.js";
19
19
  import { NumeralsContext } from "./theme/numerals.js";
20
- import { firstSelectedDay } from "./calendar/selection.js";
21
20
  import PickerContainer from "./container/PickerContainer.js";
22
21
  import { formatDateText, formatMultipleText, formatRangeText, formatValueText } from "./field/fieldText.js";
23
22
  import FieldMessages from "./field/FieldMessages.js";
@@ -41,19 +40,6 @@ const RTL = {
41
40
  direction: 'rtl'
42
41
  };
43
42
 
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
- };
56
-
57
43
  /** Minute steps that divide the hour. */
58
44
  const MINUTE_STEPS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60];
59
45
 
@@ -570,10 +556,10 @@ const DateTimePicker = props => {
570
556
  };
571
557
  const valueKey = JSON.stringify(value ?? '');
572
558
 
573
- // A selection belongs to the calendar it was picked in (Gregorian or Hijri):
574
- // it shows only there, and the field writes it in that calendar. A saved
575
- // value remembers its calendar; one from outside counts as picked in the
576
- // calendar the picker opens on.
559
+ // A selection shows in both tabs (Gregorian and Hijri). It is saved with the
560
+ // calendar on screen, and the on-screen field writes it in that calendar. A
561
+ // saved value remembers its calendar; one from outside counts as picked in
562
+ // the calendar the picker opens on.
577
563
  // The saved value as a draft, for the on-screen field and for comparing
578
564
  // values by what they hold.
579
565
  const saved = useMemo(() => createDraft(mode, value, draftOptions),
@@ -584,32 +570,12 @@ const DateTimePicker = props => {
584
570
  const savedContent = contentOf(saved);
585
571
  const savedSystemRef = useRef(null);
586
572
  const savedSystem = savedSystemRef.current?.content === savedContent ? savedSystemRef.current.system : outsideSystem;
587
- const [draftSystem, setDraftSystem] = useState(savedSystem);
588
- // The draft is rebuilt on open and on a new value; so is its calendar. A new
589
- // calendarSystem prop while the user is picking starts the selection over,
590
- // since a selection is one calendar's.
591
- const systemSeen = useRef({
592
- isOpen,
593
- valueKey,
594
- savedSystem
595
- });
596
- useEffect(() => {
597
- const seen = systemSeen.current;
598
- systemSeen.current = {
599
- isOpen,
600
- valueKey,
601
- savedSystem
602
- };
603
- setDraftSystem(savedSystem);
604
- const systemOnly = seen.isOpen === isOpen && seen.valueKey === valueKey && seen.savedSystem !== savedSystem;
605
- if (systemOnly && isOpen && edited.current) {
606
- draft.clear();
607
- resetSelectionUi();
608
- }
609
- // eslint-disable-next-line react-hooks/exhaustive-deps -- the draft's actions are stable
610
- }, [isOpen, valueKey, savedSystem]);
611
- useEffect(() => setDualTab(dualDefaultTab), [isOpen, dualDefaultTab]);
612
- const selectionShown = draftSystem === shownSystem;
573
+ const hasSaved = valuesOf(saved).some(v => v !== null);
574
+ // Each open starts on the tab the saved value was saved with; with no value,
575
+ // on dualDefaultTab.
576
+ useEffect(() => setDualTab(hasSaved ? savedSystem : dualDefaultTab),
577
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- on open and on a new dualDefaultTab, not on every save
578
+ [isOpen, dualDefaultTab]);
613
579
  /** Saves a value: with the calendar it was picked in, when one can be Hijri. */
614
580
  const emitChange = useCallback((wire, picked) => {
615
581
  savedSystemRef.current = {
@@ -633,11 +599,12 @@ const DateTimePicker = props => {
633
599
  bounds: constraints.timeBounds(v.date)
634
600
  }) === null)) && !typingBlocked && !wheelSpinning && !confirmDisabled;
635
601
 
636
- // Every save: Confirm, an 'instant' edit (onConfirm is added by `confirm`).
602
+ // Every save: Confirm, an 'instant' edit (onConfirm is added by `confirm`),
603
+ // with the calendar on screen.
637
604
  const commit = useCallback(wire => {
638
- emitChange(wire, draftSystem);
605
+ emitChange(wire, shownSystem);
639
606
  onBlur?.();
640
- }, [emitChange, draftSystem, onBlur]);
607
+ }, [emitChange, shownSystem, onBlur]);
641
608
  const confirm = useCallback(() => {
642
609
  if (!canConfirm) return;
643
610
  const {
@@ -669,8 +636,8 @@ const DateTimePicker = props => {
669
636
  draft.clear();
670
637
  resetSelectionUi();
671
638
  edited.current = false;
672
- emitChange('', draftSystem);
673
- }, [draft, emitChange, draftSystem, resetSelectionUi]);
639
+ emitChange('', shownSystem);
640
+ }, [draft, emitChange, shownSystem, resetSelectionUi]);
674
641
  const clearDraft = useCallback(() => {
675
642
  edited.current = true;
676
643
  draft.clear();
@@ -679,7 +646,6 @@ const DateTimePicker = props => {
679
646
 
680
647
  // × in the field above the calendar. 'instant' saves every edit, so it
681
648
  // clears the saved value too (once; an empty value isn't saved again).
682
- const hasSaved = valuesOf(saved).some(v => v !== null);
683
649
  const clearInSheet = useCallback(() => {
684
650
  if (commitMode === 'instant' && hasSaved) clearValue();else clearDraft();
685
651
  }, [commitMode, hasSaved, clearValue, clearDraft]);
@@ -691,7 +657,8 @@ const DateTimePicker = props => {
691
657
  // Confirm press, but only while open (closing discards, as with Confirm),
692
658
  // and only what the draft holds: a time still being typed isn't saved yet.
693
659
  // An edit equal to the saved value isn't saved again; one `validate`
694
- // rejected waits until the selection or the saved value changes.
660
+ // rejected waits until the selection or the saved value changes. A tab
661
+ // change the user makes saves the selection again with the new calendar.
695
662
  const lastRejected = useRef(null);
696
663
  // The last value saved: not saved again while the parent's `value` catches
697
664
  // up (a slow store, a server round trip) or when it never does.
@@ -709,11 +676,12 @@ const DateTimePicker = props => {
709
676
  if (!typingDone || timeIssue || !canSave(draft.draft)) return;
710
677
  const wire = draft.toWire();
711
678
  const key = JSON.stringify(wire);
712
- if (key === lastRejected.current || key === lastEmitted.current) return;
713
- // The same dates picked in the same calendar aren't saved again; the same
714
- // dates picked in the other calendar are.
679
+ const sent = `${shownSystem} ${key}`;
680
+ if (key === lastRejected.current || sent === lastEmitted.current) return;
681
+ // The same dates in the same calendar aren't saved again; the same dates
682
+ // with the other tab on screen are.
715
683
  const unchanged = key === valueKey || contentOf(draft.draft) === savedContent;
716
- if (unchanged && draftSystem === savedSystem) return;
684
+ if (unchanged && shownSystem === savedSystem) return;
717
685
  const message = latest.current.validate?.(wire);
718
686
  if (message) {
719
687
  lastRejected.current = key;
@@ -724,14 +692,14 @@ const DateTimePicker = props => {
724
692
  latest.current.onError?.('VALIDATION', wire);
725
693
  return;
726
694
  }
727
- lastEmitted.current = key;
695
+ lastEmitted.current = sent;
728
696
  commit(wire);
729
697
  };
730
698
  // Only typing waits for the field to be left; a tap is a finished edit.
731
699
  const typedLast = useRef(false);
732
700
  useEffect(() => saveInstant(!sheetTyping || !typedLast.current),
733
701
  // eslint-disable-next-line react-hooks/exhaustive-deps -- when the draft or what blocks it changes, not when callbacks are re-created
734
- [commitMode, isOpen, sheetTyping, draft.draft, draftSystem, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
702
+ [commitMode, isOpen, sheetTyping, draft.draft, shownSystem, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
735
703
  // Closing while the sheet's field still has focus ends the typing: an
736
704
  // instant picker saves what was typed before it closes.
737
705
  const saveInstantRef = useRef(saveInstant);
@@ -747,16 +715,9 @@ const DateTimePicker = props => {
747
715
  date: parsed.dateOnly,
748
716
  time: fixedTime ?? pending[key] ?? newTime()
749
717
  } : null);
750
-
751
- // Typed segments are Gregorian, so typing keeps the calendar a selection was
752
- // picked in; into an empty draft, it takes the calendar on screen.
753
- const adoptShownIfEmpty = () => {
754
- if (valuesOf(d).every(v => v === null)) setDraftSystem(shownSystem);
755
- };
756
718
  const onSheetTyped = parsed => {
757
719
  edited.current = true;
758
720
  typedLast.current = true;
759
- adoptShownIfEmpty();
760
721
  const typed = withFilledTime(parsed, 'single');
761
722
  setTypingBlock('single', !parsed.isEmpty && !typed);
762
723
  if (typed) draft.setValue(typed, 'single');else if (parsed.isEmpty) draft.clear();
@@ -764,7 +725,6 @@ const DateTimePicker = props => {
764
725
  const onRangeTyped = (end, parsed) => {
765
726
  edited.current = true;
766
727
  typedLast.current = true;
767
- adoptShownIfEmpty();
768
728
  const typed = withFilledTime(parsed, end);
769
729
  setTypingBlock(end, !parsed.isEmpty && !typed);
770
730
  if (typed || parsed.isEmpty) draft.setValue(typed, end);
@@ -810,56 +770,45 @@ const DateTimePicker = props => {
810
770
  const onSelectDay = useCallback(day => {
811
771
  edited.current = true;
812
772
  typedLast.current = false;
813
- // A pick in the other calendar starts over: the selection is one calendar's.
814
- const fresh = draftSystem !== shownSystem && valuesOf(d).some(v => v !== null);
815
- setDraftSystem(shownSystem);
816
- const cur = fresh ? emptied(d) : d;
817
- const end0 = fresh ? 'from' : activeEnd;
818
- const dayInEdit = fresh ? null : activeDay;
819
- const times = fresh ? {} : pending;
820
- if (fresh) {
821
- draft.clear();
822
- resetSelectionUi();
823
- }
824
773
  // A multiple picker scrolls for its first date only, so more can be picked.
825
- if (cur.mode !== 'multiple' || cur.slots.length === 0) revealTime();
826
- if (cur.mode === 'range') {
774
+ if (d.mode !== 'multiple' || d.slots.length === 0) revealTime();
775
+ if (d.mode === 'range') {
827
776
  if (rangeLayout === 'fromTo') {
828
777
  setEndPicked(false);
829
778
  // A full range: the tap starts a new one (or moves the nearest end).
830
- if (!endPicked && cur.from.value && cur.to.value) {
779
+ if (!endPicked && d.from.value && d.to.value) {
831
780
  const moveNearest = range?.reselect === 'moveNearestEnd';
832
- const nearest = Math.abs(daysBetween(cur.from.value.date, day)) < Math.abs(daysBetween(cur.to.value.date, day)) ? 'from' : 'to';
781
+ const nearest = Math.abs(daysBetween(d.from.value.date, day)) < Math.abs(daysBetween(d.to.value.date, day)) ? 'from' : 'to';
833
782
  const end = moveNearest ? nearest : 'from';
834
783
  setTypingBlock('from', false);
835
784
  setTypingBlock('to', false);
836
- draft.selectDay(day, fixedTime ?? times[end] ?? newTime());
785
+ draft.selectDay(day, fixedTime ?? pending[end] ?? newTime());
837
786
  setActiveEnd(moveNearest ? nearest : 'to');
838
787
  return;
839
788
  }
840
789
  // Choosing the end after a start tap: a day before the start moves the start.
841
- const end1 = end0 === 'to' && !endPicked && cur.from.value && compareCalendarDates(day, cur.from.value.date) < 0 ? 'from' : end0;
790
+ const end1 = activeEnd === 'to' && !endPicked && d.from.value && compareCalendarDates(day, d.from.value.date) < 0 ? 'from' : activeEnd;
842
791
  // The tapped day replaces whatever was typed in this end only.
843
792
  setTypingBlock(end1, false);
844
- draft.setRangeEnd(day, end1, end1 === 'to' ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times.from ?? newTime());
793
+ draft.setRangeEnd(day, end1, end1 === 'to' ? endTimeFor(d.from.value, day, pending.to) : fixedTime ?? pending.from ?? newTime());
845
794
  // The start tapped again where a range can't be one day deselects
846
795
  // it, so the next tap picks the start again.
847
- const deselects = end1 === 'to' && !sameDayRangeOk(draftOptions) && isSameDay(cur.from.value?.date, day);
848
- if (end0 === 'from') setActiveEnd('to');else if (deselects) setActiveEnd('from');
796
+ const deselects = end1 === 'to' && !sameDayRangeOk(draftOptions) && isSameDay(d.from.value?.date, day);
797
+ if (activeEnd === 'from') setActiveEnd('to');else if (deselects) setActiveEnd('from');
849
798
  return;
850
799
  }
851
800
  // The single field: the first tap is the start, the next one the end.
852
- const startsOver = !cur.from.value || !!cur.to.value && range?.reselect !== 'moveNearestEnd';
801
+ const startsOver = !d.from.value || !!d.to.value && range?.reselect !== 'moveNearestEnd';
853
802
  const end = startsOver ? 'from' : 'to';
854
803
  setTypingBlock('single', false);
855
- draft.selectDay(day, end === 'to' && !cur.to.value ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times[end] ?? newTime());
804
+ draft.selectDay(day, end === 'to' && !d.to.value ? endTimeFor(d.from.value, day, pending.to) : fixedTime ?? pending[end] ?? newTime());
856
805
  return;
857
806
  }
858
- if (cur.mode === 'multiple') {
807
+ if (d.mode === 'multiple') {
859
808
  const perDate = type === 'datetime' && multipleTimeMode === 'perDate';
860
- const picked = cur.slots.some(slot => isSameDay(slot.value?.date, day));
809
+ const picked = d.slots.some(slot => isSameDay(slot.value?.date, day));
861
810
  // perDate: a tap on a picked day first makes it the one the time row edits.
862
- if (perDate && picked && !isSameDay(dayInEdit, day)) {
811
+ if (perDate && picked && !isSameDay(activeDay, day)) {
863
812
  setActiveDay(day);
864
813
  return;
865
814
  }
@@ -868,10 +817,10 @@ const DateTimePicker = props => {
868
817
  return;
869
818
  }
870
819
  setTypingBlock('single', false);
871
- draft.selectDay(day, fixedTime ?? times.single ?? newTime());
820
+ draft.selectDay(day, fixedTime ?? pending.single ?? newTime());
872
821
  },
873
822
  // eslint-disable-next-line react-hooks/exhaustive-deps -- valuesOf reads only `d` and props listed here
874
- [d, draft, newTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock, draftSystem, shownSystem, resetSelectionUi, endPicked, draftOptions, minuteStep, constraints, revealTime]);
823
+ [d, draft, newTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock, endPicked, draftOptions, minuteStep, constraints, revealTime]);
875
824
 
876
825
  // The calendar gets a tap handler that never changes, so its memoized day
877
826
  // cells don't all redraw on every tap; it calls the current one.
@@ -994,11 +943,10 @@ const DateTimePicker = props => {
994
943
  // The calendar the on-screen field writes the saved value in.
995
944
  const fieldSystem = fieldCalendar === 'gregory' ? 'gregory' : savedSystem;
996
945
  const savedDateText = dateTextFor(fieldSystem);
997
- const draftDateText = dateTextFor(draftSystem);
946
+ const draftDateText = dateTextFor(shownSystem);
998
947
  const savedStrings = stringsFor(fieldSystem);
999
- const draftStrings = stringsFor(draftSystem);
1000
- // Error messages inside the picker follow the tab on screen; the on-screen
1001
- // field's keep `strings`.
948
+ // The texts inside the picker, its error messages too, follow the tab on
949
+ // screen; the on-screen field's keep `strings`.
1002
950
  const shownStrings = stringsFor(shownSystem);
1003
951
 
1004
952
  // What the on-screen field shows: the saved value, never the draft.
@@ -1050,11 +998,12 @@ const DateTimePicker = props => {
1050
998
  };
1051
999
  const sheetValue = draft.draft.mode === 'single' ? draft.draft.slot.value : null;
1052
1000
  // A time outside the limits is explained under the time row, not here.
1053
- const sheetValueError = sheetValue && dayOff(sheetValue.date) ? shownStrings.errorNotAllowed : '';
1001
+ const notAllowedError = sheetOptions?.showNotAllowedError === false ? '' : shownStrings.errorNotAllowed;
1002
+ const sheetValueError = sheetValue && dayOff(sheetValue.date) ? notAllowedError : '';
1054
1003
  let rangeError = '';
1055
1004
  if (d.mode === 'range' && d.from.value && d.to.value) {
1056
1005
  const length = daysBetween(d.from.value.date, d.to.value.date) + 1;
1057
- if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError = shownStrings.errorNotAllowed;else if (previewIssue === 'RANGE_ORDER') rangeError = shownStrings.errorRangeOrder;else if (previewIssue === 'RANGE_LENGTH') rangeError = range?.minDays !== undefined && length < range.minDays ? shownStrings.errorRangeTooShort(range.minDays) : shownStrings.errorRangeTooLong(range?.maxDays ?? length);
1006
+ if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError = notAllowedError;else if (previewIssue === 'RANGE_ORDER') rangeError = shownStrings.errorRangeOrder;else if (previewIssue === 'RANGE_LENGTH') rangeError = range?.minDays !== undefined && length < range.minDays ? shownStrings.errorRangeTooShort(range.minDays) : shownStrings.errorRangeTooLong(range?.maxDays ?? length);
1058
1007
  }
1059
1008
  const fieldCommon = {
1060
1009
  type,
@@ -1104,7 +1053,7 @@ const DateTimePicker = props => {
1104
1053
  testID: testID ? `${testID}-value` : undefined
1105
1054
  }) : mode === 'single' ? /*#__PURE__*/_jsx(ValueField, {
1106
1055
  ...fieldCommon,
1107
- strings: draftStrings,
1056
+ strings: shownStrings,
1108
1057
  errorStrings: shownStrings,
1109
1058
  value: sheetValue,
1110
1059
  displayText: precision !== 'day' ? periodText(sheetValue) : undefined,
@@ -1121,7 +1070,7 @@ const DateTimePicker = props => {
1121
1070
  testID: testID ? `${testID}-value` : undefined
1122
1071
  }) : d.mode === 'range' ? /*#__PURE__*/_jsx(RangeFields, {
1123
1072
  ...fieldCommon,
1124
- strings: draftStrings,
1073
+ strings: shownStrings,
1125
1074
  errorStrings: shownStrings,
1126
1075
  layout: rangeLayout,
1127
1076
  dateText: draftDateText,
@@ -1141,9 +1090,9 @@ const DateTimePicker = props => {
1141
1090
  testID: testID
1142
1091
  }) : d.mode === 'multiple' ? /*#__PURE__*/_jsx(ValueField, {
1143
1092
  ...fieldCommon,
1144
- strings: draftStrings,
1093
+ strings: shownStrings,
1145
1094
  value: null,
1146
- displayText: formatMultipleText(draftValues, type, dateFormat, timeFormat, draftDateText, draftStrings),
1095
+ displayText: formatMultipleText(draftValues, type, dateFormat, timeFormat, draftDateText, shownStrings),
1147
1096
  placeholder: sheetOptions?.fieldPlaceholder,
1148
1097
  allowClear: allowClear,
1149
1098
  onClear: clearInSheet,
@@ -1158,13 +1107,20 @@ const DateTimePicker = props => {
1158
1107
  dual: strings.calendarDual ?? DEFAULT_STRINGS.calendarDual
1159
1108
  };
1160
1109
  const systemA11yLabel = strings.a11yCalendarSystem ?? DEFAULT_STRINGS.a11yCalendarSystem;
1110
+ // A calendar or tab the user picks is an edit: 'instant' saves the selection
1111
+ // again with that calendar.
1161
1112
  const chooseSystem = next => {
1162
1113
  if (next === system) return;
1114
+ edited.current = true;
1163
1115
  setChosenSystem(next);
1164
1116
  if (next === 'dual') setDualTab(dualDefaultTab);
1165
1117
  echo.current = next;
1166
1118
  onCalendarSystemChange?.(next);
1167
1119
  };
1120
+ const chooseTab = next => {
1121
+ edited.current = true;
1122
+ setDualTab(next);
1123
+ };
1168
1124
  const calendarSwitchNode = !switchSystems ? null : renderCalendarSwitch ? renderCalendarSwitch({
1169
1125
  systems: switchSystems,
1170
1126
  selected: system,
@@ -1196,7 +1152,7 @@ const DateTimePicker = props => {
1196
1152
  label: systemLabels.hijri
1197
1153
  }],
1198
1154
  selected: dualTab,
1199
- onSelect: setDualTab,
1155
+ onSelect: chooseTab,
1200
1156
  accessibilityLabel: systemA11yLabel,
1201
1157
  tokens: tokens,
1202
1158
  styles: styles,
@@ -1212,16 +1168,16 @@ const DateTimePicker = props => {
1212
1168
  children: node
1213
1169
  })
1214
1170
  });
1215
- // Another calendar opens on the days the last one showed, else on the
1216
- // selection (shown or not), else where the picker would open.
1217
- const calendarAnchor = shownAnchor.current ?? (selectionShown ? null : firstSelectedDay(selection)) ?? initialVisibleDate;
1171
+ // Another calendar opens on the days the last one showed, else where the
1172
+ // picker would open.
1173
+ const calendarAnchor = shownAnchor.current ?? initialVisibleDate;
1218
1174
  const calendar = /*#__PURE__*/_jsxs(View, {
1219
1175
  style: folded ? FOLDED : undefined,
1220
1176
  children: [calendarSwitchNode, dualTabs, mirrored(/*#__PURE__*/_jsx(Calendar, {
1221
- constraints: selectionShown ? calendarConstraints : constraints,
1177
+ constraints: calendarConstraints,
1222
1178
  today: today,
1223
1179
  initialVisibleDate: calendarAnchor,
1224
- selection: selectionShown ? selection : emptySelection(selection),
1180
+ selection: selection,
1225
1181
  onSelectDay: onSelectDayStable,
1226
1182
  firstDayOfWeek: firstDayOfWeek,
1227
1183
  showOutsideDays: showOutsideDays,
@@ -1284,15 +1240,11 @@ const DateTimePicker = props => {
1284
1240
  // Shown while the selection is still the one it was given for.
1285
1241
  const validationMessage = validation && (validation.key === JSON.stringify(draft.toWire()) || validation.key === JSON.stringify(draftToWire(preview, draftOptions))) ? validation.message : null;
1286
1242
 
1287
- // The field writes the date in the digits of the calendar it was picked in;
1288
- // the calendar and the time rows follow the tab that shows.
1243
+ // The field, the calendar and the time rows follow the tab that shows.
1289
1244
  const sheetContent = /*#__PURE__*/_jsxs(_Fragment, {
1290
- children: [/*#__PURE__*/_jsx(NumeralsContext.Provider, {
1291
- value: digitsFor(draftSystem),
1292
- children: sheetField
1293
- }), /*#__PURE__*/_jsx(NumeralsContext.Provider, {
1245
+ children: [/*#__PURE__*/_jsxs(NumeralsContext.Provider, {
1294
1246
  value: digitsFor(shownSystem),
1295
- children: calendar
1247
+ children: [sheetField, calendar]
1296
1248
  }), timeRow == null ? null :
1297
1249
  /*#__PURE__*/
1298
1250
  // Measured for the scroll to the time (sheet.scrollToTime).