@cdx-ui/formatters 0.2.0 → 0.2.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.
- package/coverage.svg +1 -1
- package/lib/commonjs/dates/index.js +13 -0
- package/lib/commonjs/dates/index.js.map +1 -1
- package/lib/commonjs/dates/labels/dateComponentLabels.js +48 -3
- package/lib/commonjs/dates/labels/dateComponentLabels.js.map +1 -1
- package/lib/commonjs/dates/validation/getDateValidationReason.js +33 -0
- package/lib/commonjs/dates/validation/getDateValidationReason.js.map +1 -0
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/dates/index.js +2 -1
- package/lib/module/dates/index.js.map +1 -1
- package/lib/module/dates/labels/dateComponentLabels.js +48 -3
- package/lib/module/dates/labels/dateComponentLabels.js.map +1 -1
- package/lib/module/dates/validation/getDateValidationReason.js +29 -0
- package/lib/module/dates/validation/getDateValidationReason.js.map +1 -0
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/dates/index.d.ts +3 -2
- package/lib/typescript/dates/index.d.ts.map +1 -1
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts +31 -2
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts.map +1 -1
- package/lib/typescript/dates/types.d.ts +11 -0
- package/lib/typescript/dates/types.d.ts.map +1 -1
- package/lib/typescript/dates/validation/getDateValidationReason.d.ts +16 -0
- package/lib/typescript/dates/validation/getDateValidationReason.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/dateComponentLabels.test.ts +55 -0
- package/src/__tests__/getDateValidationReason.test.ts +45 -0
- package/src/dates/index.ts +5 -0
- package/src/dates/labels/dateComponentLabels.ts +68 -2
- package/src/dates/types.ts +13 -0
- package/src/dates/validation/getDateValidationReason.ts +31 -0
- package/src/index.ts +5 -0
package/coverage.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="108" height="20" role="img" aria-label="coverage: 95.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="108" height="20" role="img" aria-label="coverage: 95.7%"><title>coverage: 95.7%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="108" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="47" height="20" fill="#4b0"/><rect width="108" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="835" y="150" fill-opacity=".8" filter="url(#blur)" textLength="370">95.7%</text><text x="835" y="150" fill-opacity=".3" textLength="370">95.7%</text></g><text x="835" y="140" textLength="370">95.7%</text></g></g></svg>
|
|
@@ -147,6 +147,12 @@ Object.defineProperty(exports, "formatDateTimeListPeriod", {
|
|
|
147
147
|
return _formatDateTimeListPeriod.formatDateTimeListPeriod;
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
|
+
Object.defineProperty(exports, "formatDateValidationMessage", {
|
|
151
|
+
enumerable: true,
|
|
152
|
+
get: function () {
|
|
153
|
+
return _dateComponentLabels.formatDateValidationMessage;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
150
156
|
Object.defineProperty(exports, "formatMonthCalendarMonth", {
|
|
151
157
|
enumerable: true,
|
|
152
158
|
get: function () {
|
|
@@ -207,6 +213,12 @@ Object.defineProperty(exports, "getDateTimeSegmentVisibility", {
|
|
|
207
213
|
return _getDateTimeSegmentVisibility.getDateTimeSegmentVisibility;
|
|
208
214
|
}
|
|
209
215
|
});
|
|
216
|
+
Object.defineProperty(exports, "getDateValidationReason", {
|
|
217
|
+
enumerable: true,
|
|
218
|
+
get: function () {
|
|
219
|
+
return _getDateValidationReason.getDateValidationReason;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
210
222
|
Object.defineProperty(exports, "getEmptyDateSegmentText", {
|
|
211
223
|
enumerable: true,
|
|
212
224
|
get: function () {
|
|
@@ -358,6 +370,7 @@ var _getDateTimeFieldSegments = require("./segments/getDateTimeFieldSegments");
|
|
|
358
370
|
var _getDateTimeSegmentVisibility = require("./segments/getDateTimeSegmentVisibility");
|
|
359
371
|
var _getEmptyDateSegmentText = require("./segments/getEmptyDateSegmentText");
|
|
360
372
|
var _parseDateSegment = require("./segments/parseDateSegment");
|
|
373
|
+
var _getDateValidationReason = require("./validation/getDateValidationReason");
|
|
361
374
|
var _formatCalendarMonthYear = require("./calendar/formatCalendarMonthYear");
|
|
362
375
|
var _formatDateTimeListDateRow = require("./calendar/formatDateTimeListDateRow");
|
|
363
376
|
var _formatMonthCalendarMonth = require("./calendar/formatMonthCalendarMonth");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_clampDateParts","require","_clampMonthParts","_dateId","_monthId","_formatDateId","_formatMonthId","_isValidDateId","_isValidDateParts","_isValidMonthId","_isValidMonthParts","_parseDateId","_parseMonthId","_toMonthId","_todayDateId","_todayMonthId","_clampDateTimeId","_compareDateTimeIds","_dateTimeId","_formatDateTimeId","_isLocaleHour","_formatDateTimeListHour","_formatDateTimeListMinute","_formatDateTimeListPeriod","_isValidDateTimeId","_nowDateTimeId","_parseDateTimeId","_formatDateForDisplay","_formatDateRangeForDisplay","_formatDateTimeForDisplay","_formatMonthForDisplay","_compareDateIds","_compareMonthIds","_dateRangeAroundDay","_dateRangeFromLastNDays","_eachDateIdInRange","_normalizeDateRange","_applyDateSegmentChange","_formatDateSegment","_getDateFieldSegments","_getDateTimeFieldSegments","_getDateTimeSegmentVisibility","_getEmptyDateSegmentText","_parseDateSegment","_formatCalendarMonthYear","_formatDateTimeListDateRow","_formatMonthCalendarMonth","_formatMonthCalendarYear","_getCalendarWeekdayLabels","_dateComponentLabels"],"sourceRoot":"../../../src","sources":["dates/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_clampDateParts","require","_clampMonthParts","_dateId","_monthId","_formatDateId","_formatMonthId","_isValidDateId","_isValidDateParts","_isValidMonthId","_isValidMonthParts","_parseDateId","_parseMonthId","_toMonthId","_todayDateId","_todayMonthId","_clampDateTimeId","_compareDateTimeIds","_dateTimeId","_formatDateTimeId","_isLocaleHour","_formatDateTimeListHour","_formatDateTimeListMinute","_formatDateTimeListPeriod","_isValidDateTimeId","_nowDateTimeId","_parseDateTimeId","_formatDateForDisplay","_formatDateRangeForDisplay","_formatDateTimeForDisplay","_formatMonthForDisplay","_compareDateIds","_compareMonthIds","_dateRangeAroundDay","_dateRangeFromLastNDays","_eachDateIdInRange","_normalizeDateRange","_applyDateSegmentChange","_formatDateSegment","_getDateFieldSegments","_getDateTimeFieldSegments","_getDateTimeSegmentVisibility","_getEmptyDateSegmentText","_parseDateSegment","_getDateValidationReason","_formatCalendarMonthYear","_formatDateTimeListDateRow","_formatMonthCalendarMonth","_formatMonthCalendarYear","_getCalendarWeekdayLabels","_dateComponentLabels"],"sourceRoot":"../../../src","sources":["dates/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AACA,IAAAI,aAAA,GAAAJ,OAAA;AACA,IAAAK,cAAA,GAAAL,OAAA;AACA,IAAAM,cAAA,GAAAN,OAAA;AACA,IAAAO,iBAAA,GAAAP,OAAA;AACA,IAAAQ,eAAA,GAAAR,OAAA;AACA,IAAAS,kBAAA,GAAAT,OAAA;AACA,IAAAU,YAAA,GAAAV,OAAA;AACA,IAAAW,aAAA,GAAAX,OAAA;AACA,IAAAY,UAAA,GAAAZ,OAAA;AACA,IAAAa,YAAA,GAAAb,OAAA;AACA,IAAAc,aAAA,GAAAd,OAAA;AAEA,IAAAe,gBAAA,GAAAf,OAAA;AACA,IAAAgB,mBAAA,GAAAhB,OAAA;AACA,IAAAiB,WAAA,GAAAjB,OAAA;AACA,IAAAkB,iBAAA,GAAAlB,OAAA;AACA,IAAAmB,aAAA,GAAAnB,OAAA;AACA,IAAAoB,uBAAA,GAAApB,OAAA;AACA,IAAAqB,yBAAA,GAAArB,OAAA;AACA,IAAAsB,yBAAA,GAAAtB,OAAA;AACA,IAAAuB,kBAAA,GAAAvB,OAAA;AACA,IAAAwB,cAAA,GAAAxB,OAAA;AACA,IAAAyB,gBAAA,GAAAzB,OAAA;AAEA,IAAA0B,qBAAA,GAAA1B,OAAA;AACA,IAAA2B,0BAAA,GAAA3B,OAAA;AACA,IAAA4B,yBAAA,GAAA5B,OAAA;AACA,IAAA6B,sBAAA,GAAA7B,OAAA;AAEA,IAAA8B,eAAA,GAAA9B,OAAA;AACA,IAAA+B,gBAAA,GAAA/B,OAAA;AACA,IAAAgC,mBAAA,GAAAhC,OAAA;AACA,IAAAiC,uBAAA,GAAAjC,OAAA;AACA,IAAAkC,kBAAA,GAAAlC,OAAA;AACA,IAAAmC,mBAAA,GAAAnC,OAAA;AAEA,IAAAoC,uBAAA,GAAApC,OAAA;AACA,IAAAqC,kBAAA,GAAArC,OAAA;AACA,IAAAsC,qBAAA,GAAAtC,OAAA;AACA,IAAAuC,yBAAA,GAAAvC,OAAA;AACA,IAAAwC,6BAAA,GAAAxC,OAAA;AACA,IAAAyC,wBAAA,GAAAzC,OAAA;AACA,IAAA0C,iBAAA,GAAA1C,OAAA;AAEA,IAAA2C,wBAAA,GAAA3C,OAAA;AAEA,IAAA4C,wBAAA,GAAA5C,OAAA;AACA,IAAA6C,0BAAA,GAAA7C,OAAA;AACA,IAAA8C,yBAAA,GAAA9C,OAAA;AACA,IAAA+C,wBAAA,GAAA/C,OAAA;AACA,IAAAgD,yBAAA,GAAAhD,OAAA;AAGA,IAAAiD,oBAAA,GAAAjD,OAAA","ignoreList":[]}
|
|
@@ -4,9 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.DEFAULT_DATE_COMPONENT_LABELS = void 0;
|
|
7
|
+
exports.formatDateValidationMessage = formatDateValidationMessage;
|
|
7
8
|
exports.formatSelectYear = formatSelectYear;
|
|
8
9
|
exports.getDateSegmentAccessibilityLabel = getDateSegmentAccessibilityLabel;
|
|
9
10
|
exports.resolveDateComponentLabels = resolveDateComponentLabels;
|
|
11
|
+
var _formatDateForDisplay = require("../display/formatDateForDisplay");
|
|
10
12
|
/** Overridable UI copy for date pickers, calendars, and segmented date fields. */
|
|
11
13
|
|
|
12
14
|
const DEFAULT_DATE_COMPONENT_LABELS = exports.DEFAULT_DATE_COMPONENT_LABELS = {
|
|
@@ -30,7 +32,11 @@ const DEFAULT_DATE_COMPONENT_LABELS = exports.DEFAULT_DATE_COMPONENT_LABELS = {
|
|
|
30
32
|
segmentMinute: 'Minute',
|
|
31
33
|
segmentSecond: 'Second',
|
|
32
34
|
segmentDayPeriod: 'AM/PM',
|
|
33
|
-
|
|
35
|
+
segmentInvalid: '{segment}, invalid',
|
|
36
|
+
rangeSeparator: '–',
|
|
37
|
+
validationBeforeMin: 'Select a date on or after {date}',
|
|
38
|
+
validationAfterMax: 'Select a date on or before {date}',
|
|
39
|
+
validationUnavailable: 'This date is unavailable'
|
|
34
40
|
};
|
|
35
41
|
function resolveDateComponentLabels(partial) {
|
|
36
42
|
return {
|
|
@@ -41,6 +47,37 @@ function resolveDateComponentLabels(partial) {
|
|
|
41
47
|
function formatSelectYear(labels, year) {
|
|
42
48
|
return labels.selectYear.replace('{year}', String(year));
|
|
43
49
|
}
|
|
50
|
+
const VALIDATION_LABEL_KEYS = {
|
|
51
|
+
beforeMin: 'validationBeforeMin',
|
|
52
|
+
afterMax: 'validationAfterMax',
|
|
53
|
+
unavailable: 'validationUnavailable'
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolves the user-facing message for a {@link DateValidationReason}.
|
|
58
|
+
*
|
|
59
|
+
* `{date}` in the min / max messages is replaced with the bound, formatted for display
|
|
60
|
+
* with `options.locale` and `options.dateStyle` (defaults: `en-US`, `medium`). `DatePicker`
|
|
61
|
+
* already formats this message with its own `labels` and `locale` (see `onValidationChange`
|
|
62
|
+
* and `Field.Error`); call this directly only outside a picker, and pass the same `locale`.
|
|
63
|
+
*
|
|
64
|
+
* @param labels - Resolved labels (see `resolveDateComponentLabels`).
|
|
65
|
+
* @param reason - Reason returned by `getDateValidationReason` or `onValidationChange`.
|
|
66
|
+
* @param rules - The bounds the reason was computed against.
|
|
67
|
+
* @param options - Display options for the `{date}` placeholder.
|
|
68
|
+
* @returns The message to render in `Field.Error`.
|
|
69
|
+
*/
|
|
70
|
+
function formatDateValidationMessage(labels, reason, rules, options) {
|
|
71
|
+
const message = labels[VALIDATION_LABEL_KEYS[reason]];
|
|
72
|
+
const bound = reason === 'beforeMin' ? rules.minValue : reason === 'afterMax' ? rules.maxValue : undefined;
|
|
73
|
+
if (bound === undefined) {
|
|
74
|
+
return message;
|
|
75
|
+
}
|
|
76
|
+
return message.replace('{date}', (0, _formatDateForDisplay.formatDateForDisplay)(bound, {
|
|
77
|
+
dateStyle: 'medium',
|
|
78
|
+
...options
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
44
81
|
const SEGMENT_LABEL_KEYS = {
|
|
45
82
|
year: 'segmentYear',
|
|
46
83
|
month: 'segmentMonth',
|
|
@@ -50,8 +87,16 @@ const SEGMENT_LABEL_KEYS = {
|
|
|
50
87
|
second: 'segmentSecond',
|
|
51
88
|
dayPeriod: 'segmentDayPeriod'
|
|
52
89
|
};
|
|
53
|
-
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param invalid - Wraps the label in `labels.segmentInvalid`, for native platforms where
|
|
93
|
+
* `aria-invalid` is not announced.
|
|
94
|
+
*/
|
|
95
|
+
function getDateSegmentAccessibilityLabel(type, labels, invalid = false) {
|
|
54
96
|
const key = SEGMENT_LABEL_KEYS[type];
|
|
55
|
-
|
|
97
|
+
if (!key) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
return invalid ? labels.segmentInvalid.replace('{segment}', labels[key]) : labels[key];
|
|
56
101
|
}
|
|
57
102
|
//# sourceMappingURL=dateComponentLabels.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DEFAULT_DATE_COMPONENT_LABELS","exports","openDatePicker","openDateTimePicker","openDateRangePicker","openMonthPicker","showCalendar","showYearPicker","showMonths","previousMonth","nextMonth","previousYear","nextYear","selectYear","dateFieldKeyboardInput","segmentYear","segmentMonth","segmentDay","segmentHour","segmentMinute","segmentSecond","segmentDayPeriod","rangeSeparator","resolveDateComponentLabels","partial","formatSelectYear","labels","year","replace","String","SEGMENT_LABEL_KEYS","month","day","hour","minute","second","dayPeriod","getDateSegmentAccessibilityLabel","type","
|
|
1
|
+
{"version":3,"names":["_formatDateForDisplay","require","DEFAULT_DATE_COMPONENT_LABELS","exports","openDatePicker","openDateTimePicker","openDateRangePicker","openMonthPicker","showCalendar","showYearPicker","showMonths","previousMonth","nextMonth","previousYear","nextYear","selectYear","dateFieldKeyboardInput","segmentYear","segmentMonth","segmentDay","segmentHour","segmentMinute","segmentSecond","segmentDayPeriod","segmentInvalid","rangeSeparator","validationBeforeMin","validationAfterMax","validationUnavailable","resolveDateComponentLabels","partial","formatSelectYear","labels","year","replace","String","VALIDATION_LABEL_KEYS","beforeMin","afterMax","unavailable","formatDateValidationMessage","reason","rules","options","message","bound","minValue","maxValue","undefined","formatDateForDisplay","dateStyle","SEGMENT_LABEL_KEYS","month","day","hour","minute","second","dayPeriod","getDateSegmentAccessibilityLabel","type","invalid","key"],"sourceRoot":"../../../../src","sources":["dates/labels/dateComponentLabels.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getDateValidationReason = getDateValidationReason;
|
|
7
|
+
var _compareDateIds = require("../ranges/compareDateIds");
|
|
8
|
+
/**
|
|
9
|
+
* Checks a complete wire date against `minValue`, `maxValue`, and `isDateUnavailable`.
|
|
10
|
+
*
|
|
11
|
+
* Bounds are inclusive and are checked before the predicate, so a date outside
|
|
12
|
+
* the range reports `beforeMin` / `afterMax` even when it is also unavailable.
|
|
13
|
+
*
|
|
14
|
+
* @param date - Wire date to check.
|
|
15
|
+
* @param rules - Bounds and unavailable-date predicate.
|
|
16
|
+
* @returns The first rule the date violates, or `undefined` when it is selectable.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* getDateValidationReason(dateId('2026-08-01'), { minValue: dateId('2026-08-10') }) // 'beforeMin'
|
|
20
|
+
*/
|
|
21
|
+
function getDateValidationReason(date, rules) {
|
|
22
|
+
if (rules.minValue !== undefined && (0, _compareDateIds.compareDateIds)(date, rules.minValue) < 0) {
|
|
23
|
+
return 'beforeMin';
|
|
24
|
+
}
|
|
25
|
+
if (rules.maxValue !== undefined && (0, _compareDateIds.compareDateIds)(date, rules.maxValue) > 0) {
|
|
26
|
+
return 'afterMax';
|
|
27
|
+
}
|
|
28
|
+
if (rules.isDateUnavailable?.(date)) {
|
|
29
|
+
return 'unavailable';
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=getDateValidationReason.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_compareDateIds","require","getDateValidationReason","date","rules","minValue","undefined","compareDateIds","maxValue","isDateUnavailable"],"sourceRoot":"../../../../src","sources":["dates/validation/getDateValidationReason.ts"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,uBAAuBA,CACrCC,IAAY,EACZC,KAA0B,EACQ;EAClC,IAAIA,KAAK,CAACC,QAAQ,KAAKC,SAAS,IAAI,IAAAC,8BAAc,EAACJ,IAAI,EAAEC,KAAK,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC5E,OAAO,WAAW;EACpB;EACA,IAAID,KAAK,CAACI,QAAQ,KAAKF,SAAS,IAAI,IAAAC,8BAAc,EAACJ,IAAI,EAAEC,KAAK,CAACI,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC5E,OAAO,UAAU;EACnB;EACA,IAAIJ,KAAK,CAACK,iBAAiB,GAAGN,IAAI,CAAC,EAAE;IACnC,OAAO,aAAa;EACtB;EACA,OAAOG,SAAS;AAClB","ignoreList":[]}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -147,6 +147,12 @@ Object.defineProperty(exports, "formatDateTimeListPeriod", {
|
|
|
147
147
|
return _dates.formatDateTimeListPeriod;
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
|
+
Object.defineProperty(exports, "formatDateValidationMessage", {
|
|
151
|
+
enumerable: true,
|
|
152
|
+
get: function () {
|
|
153
|
+
return _dates.formatDateValidationMessage;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
150
156
|
Object.defineProperty(exports, "formatMonthCalendarMonth", {
|
|
151
157
|
enumerable: true,
|
|
152
158
|
get: function () {
|
|
@@ -213,6 +219,12 @@ Object.defineProperty(exports, "getDateTimeSegmentVisibility", {
|
|
|
213
219
|
return _dates.getDateTimeSegmentVisibility;
|
|
214
220
|
}
|
|
215
221
|
});
|
|
222
|
+
Object.defineProperty(exports, "getDateValidationReason", {
|
|
223
|
+
enumerable: true,
|
|
224
|
+
get: function () {
|
|
225
|
+
return _dates.getDateValidationReason;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
216
228
|
Object.defineProperty(exports, "getEmptyDateSegmentText", {
|
|
217
229
|
enumerable: true,
|
|
218
230
|
get: function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_formatNumber","require","_dates"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_formatNumber","require","_dates"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AAsBA,IAAAC,MAAA,GAAAD,OAAA","ignoreList":[]}
|
|
@@ -50,10 +50,11 @@ export { getDateTimeFieldSegments } from './segments/getDateTimeFieldSegments';
|
|
|
50
50
|
export { getDateTimeSegmentVisibility } from './segments/getDateTimeSegmentVisibility';
|
|
51
51
|
export { getEmptyDateSegmentText } from './segments/getEmptyDateSegmentText';
|
|
52
52
|
export { parseDateSegment } from './segments/parseDateSegment';
|
|
53
|
+
export { getDateValidationReason } from './validation/getDateValidationReason';
|
|
53
54
|
export { formatCalendarMonthYear } from './calendar/formatCalendarMonthYear';
|
|
54
55
|
export { formatDateTimeListDateRow } from './calendar/formatDateTimeListDateRow';
|
|
55
56
|
export { formatMonthCalendarMonth } from './calendar/formatMonthCalendarMonth';
|
|
56
57
|
export { formatMonthCalendarYear } from './calendar/formatMonthCalendarYear';
|
|
57
58
|
export { getCalendarWeekdayLabels } from './calendar/getCalendarWeekdayLabels';
|
|
58
|
-
export { DEFAULT_DATE_COMPONENT_LABELS, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels } from './labels/dateComponentLabels';
|
|
59
|
+
export { DEFAULT_DATE_COMPONENT_LABELS, formatDateValidationMessage, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels } from './labels/dateComponentLabels';
|
|
59
60
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["clampDateParts","clampMonthParts","dateId","monthId","formatDateId","formatMonthId","isValidDateId","isValidDateParts","isValidMonthId","isValidMonthParts","parseDateId","parseMonthId","toMonthId","todayDateId","todayMonthId","clampDateTimeId","compareDateTimeIds","dateTimeId","formatDateTimeId","isLocaleHour12","formatDateTimeListHour","formatDateTimeListMinute","formatDateTimeListPeriod","isValidDateTimeId","nowDateTimeId","parseDateTimeId","formatDateForDisplay","formatDateRangeForDisplay","formatDateTimeForDisplay","formatMonthForDisplay","compareDateIds","compareMonthIds","dateRangeAroundDay","dateRangeFromLastNDays","eachDateIdInRange","normalizeDateRange","applyDateSegmentChange","formatDateSegment","getDateFieldSegments","getDateTimeFieldSegments","getDateTimeSegmentVisibility","getEmptyDateSegmentText","parseDateSegment","formatCalendarMonthYear","formatDateTimeListDateRow","formatMonthCalendarMonth","formatMonthCalendarYear","getCalendarWeekdayLabels","DEFAULT_DATE_COMPONENT_LABELS","formatSelectYear","getDateSegmentAccessibilityLabel","resolveDateComponentLabels"],"sourceRoot":"../../../src","sources":["dates/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["clampDateParts","clampMonthParts","dateId","monthId","formatDateId","formatMonthId","isValidDateId","isValidDateParts","isValidMonthId","isValidMonthParts","parseDateId","parseMonthId","toMonthId","todayDateId","todayMonthId","clampDateTimeId","compareDateTimeIds","dateTimeId","formatDateTimeId","isLocaleHour12","formatDateTimeListHour","formatDateTimeListMinute","formatDateTimeListPeriod","isValidDateTimeId","nowDateTimeId","parseDateTimeId","formatDateForDisplay","formatDateRangeForDisplay","formatDateTimeForDisplay","formatMonthForDisplay","compareDateIds","compareMonthIds","dateRangeAroundDay","dateRangeFromLastNDays","eachDateIdInRange","normalizeDateRange","applyDateSegmentChange","formatDateSegment","getDateFieldSegments","getDateTimeFieldSegments","getDateTimeSegmentVisibility","getEmptyDateSegmentText","parseDateSegment","getDateValidationReason","formatCalendarMonthYear","formatDateTimeListDateRow","formatMonthCalendarMonth","formatMonthCalendarYear","getCalendarWeekdayLabels","DEFAULT_DATE_COMPONENT_LABELS","formatDateValidationMessage","formatSelectYear","getDateSegmentAccessibilityLabel","resolveDateComponentLabels"],"sourceRoot":"../../../src","sources":["dates/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;;AAsBA,SAASA,cAAc,QAAQ,uBAAuB;AACtD,SAASC,eAAe,QAAQ,wBAAwB;AACxD,SAASC,MAAM,QAAQ,eAAe;AACtC,SAASC,OAAO,QAAQ,gBAAgB;AACxC,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAASC,gBAAgB,QAAQ,yBAAyB;AAC1D,SAASC,cAAc,QAAQ,uBAAuB;AACtD,SAASC,iBAAiB,QAAQ,0BAA0B;AAC5D,SAASC,WAAW,QAAQ,oBAAoB;AAChD,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,SAAS,QAAQ,kBAAkB;AAC5C,SAASC,WAAW,QAAQ,oBAAoB;AAChD,SAASC,YAAY,QAAQ,qBAAqB;AAElD,SAASC,eAAe,QAAQ,4BAA4B;AAC5D,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,UAAU,QAAQ,uBAAuB;AAClD,SAASC,gBAAgB,QAAQ,6BAA6B;AAC9D,SAASC,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,sBAAsB,QAAQ,mCAAmC;AAC1E,SAASC,wBAAwB,QAAQ,qCAAqC;AAC9E,SAASC,wBAAwB,QAAQ,qCAAqC;AAC9E,SAASC,iBAAiB,QAAQ,8BAA8B;AAChE,SAASC,aAAa,QAAQ,0BAA0B;AACxD,SAASC,eAAe,QAAQ,4BAA4B;AAE5D,SAASC,oBAAoB,QAAQ,gCAAgC;AACrE,SAASC,yBAAyB,QAAQ,qCAAqC;AAC/E,SAASC,wBAAwB,QAAQ,oCAAoC;AAC7E,SAASC,qBAAqB,QAAQ,iCAAiC;AAEvE,SAASC,cAAc,QAAQ,yBAAyB;AACxD,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,kBAAkB,QAAQ,6BAA6B;AAChE,SAASC,sBAAsB,QAAQ,iCAAiC;AACxE,SAASC,iBAAiB,QAAQ,4BAA4B;AAC9D,SAASC,kBAAkB,QAAQ,6BAA6B;AAEhE,SAASC,sBAAsB,QAAQ,mCAAmC;AAC1E,SAASC,iBAAiB,QAAQ,8BAA8B;AAChE,SAASC,oBAAoB,QAAQ,iCAAiC;AACtE,SAASC,wBAAwB,QAAQ,qCAAqC;AAC9E,SAASC,4BAA4B,QAAQ,yCAAyC;AACtF,SAASC,uBAAuB,QAAQ,oCAAoC;AAC5E,SAASC,gBAAgB,QAAQ,6BAA6B;AAE9D,SAASC,uBAAuB,QAAQ,sCAAsC;AAE9E,SAASC,uBAAuB,QAAQ,oCAAoC;AAC5E,SAASC,yBAAyB,QAAQ,sCAAsC;AAChF,SAASC,wBAAwB,QAAQ,qCAAqC;AAC9E,SAASC,uBAAuB,QAAQ,oCAAoC;AAC5E,SAASC,wBAAwB,QAAQ,qCAAqC;AAG9E,SACEC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,gBAAgB,EAChBC,gCAAgC,EAChCC,0BAA0B,QACrB,8BAA8B","ignoreList":[]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { formatDateForDisplay } from '../display/formatDateForDisplay';
|
|
4
|
+
|
|
3
5
|
/** Overridable UI copy for date pickers, calendars, and segmented date fields. */
|
|
4
6
|
|
|
5
7
|
export const DEFAULT_DATE_COMPONENT_LABELS = {
|
|
@@ -23,7 +25,11 @@ export const DEFAULT_DATE_COMPONENT_LABELS = {
|
|
|
23
25
|
segmentMinute: 'Minute',
|
|
24
26
|
segmentSecond: 'Second',
|
|
25
27
|
segmentDayPeriod: 'AM/PM',
|
|
26
|
-
|
|
28
|
+
segmentInvalid: '{segment}, invalid',
|
|
29
|
+
rangeSeparator: '–',
|
|
30
|
+
validationBeforeMin: 'Select a date on or after {date}',
|
|
31
|
+
validationAfterMax: 'Select a date on or before {date}',
|
|
32
|
+
validationUnavailable: 'This date is unavailable'
|
|
27
33
|
};
|
|
28
34
|
export function resolveDateComponentLabels(partial) {
|
|
29
35
|
return {
|
|
@@ -34,6 +40,37 @@ export function resolveDateComponentLabels(partial) {
|
|
|
34
40
|
export function formatSelectYear(labels, year) {
|
|
35
41
|
return labels.selectYear.replace('{year}', String(year));
|
|
36
42
|
}
|
|
43
|
+
const VALIDATION_LABEL_KEYS = {
|
|
44
|
+
beforeMin: 'validationBeforeMin',
|
|
45
|
+
afterMax: 'validationAfterMax',
|
|
46
|
+
unavailable: 'validationUnavailable'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the user-facing message for a {@link DateValidationReason}.
|
|
51
|
+
*
|
|
52
|
+
* `{date}` in the min / max messages is replaced with the bound, formatted for display
|
|
53
|
+
* with `options.locale` and `options.dateStyle` (defaults: `en-US`, `medium`). `DatePicker`
|
|
54
|
+
* already formats this message with its own `labels` and `locale` (see `onValidationChange`
|
|
55
|
+
* and `Field.Error`); call this directly only outside a picker, and pass the same `locale`.
|
|
56
|
+
*
|
|
57
|
+
* @param labels - Resolved labels (see `resolveDateComponentLabels`).
|
|
58
|
+
* @param reason - Reason returned by `getDateValidationReason` or `onValidationChange`.
|
|
59
|
+
* @param rules - The bounds the reason was computed against.
|
|
60
|
+
* @param options - Display options for the `{date}` placeholder.
|
|
61
|
+
* @returns The message to render in `Field.Error`.
|
|
62
|
+
*/
|
|
63
|
+
export function formatDateValidationMessage(labels, reason, rules, options) {
|
|
64
|
+
const message = labels[VALIDATION_LABEL_KEYS[reason]];
|
|
65
|
+
const bound = reason === 'beforeMin' ? rules.minValue : reason === 'afterMax' ? rules.maxValue : undefined;
|
|
66
|
+
if (bound === undefined) {
|
|
67
|
+
return message;
|
|
68
|
+
}
|
|
69
|
+
return message.replace('{date}', formatDateForDisplay(bound, {
|
|
70
|
+
dateStyle: 'medium',
|
|
71
|
+
...options
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
37
74
|
const SEGMENT_LABEL_KEYS = {
|
|
38
75
|
year: 'segmentYear',
|
|
39
76
|
month: 'segmentMonth',
|
|
@@ -43,8 +80,16 @@ const SEGMENT_LABEL_KEYS = {
|
|
|
43
80
|
second: 'segmentSecond',
|
|
44
81
|
dayPeriod: 'segmentDayPeriod'
|
|
45
82
|
};
|
|
46
|
-
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param invalid - Wraps the label in `labels.segmentInvalid`, for native platforms where
|
|
86
|
+
* `aria-invalid` is not announced.
|
|
87
|
+
*/
|
|
88
|
+
export function getDateSegmentAccessibilityLabel(type, labels, invalid = false) {
|
|
47
89
|
const key = SEGMENT_LABEL_KEYS[type];
|
|
48
|
-
|
|
90
|
+
if (!key) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return invalid ? labels.segmentInvalid.replace('{segment}', labels[key]) : labels[key];
|
|
49
94
|
}
|
|
50
95
|
//# sourceMappingURL=dateComponentLabels.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DEFAULT_DATE_COMPONENT_LABELS","openDatePicker","openDateTimePicker","openDateRangePicker","openMonthPicker","showCalendar","showYearPicker","showMonths","previousMonth","nextMonth","previousYear","nextYear","selectYear","dateFieldKeyboardInput","segmentYear","segmentMonth","segmentDay","segmentHour","segmentMinute","segmentSecond","segmentDayPeriod","rangeSeparator","resolveDateComponentLabels","partial","formatSelectYear","labels","year","replace","String","SEGMENT_LABEL_KEYS","month","day","hour","minute","second","dayPeriod","getDateSegmentAccessibilityLabel","type","
|
|
1
|
+
{"version":3,"names":["formatDateForDisplay","DEFAULT_DATE_COMPONENT_LABELS","openDatePicker","openDateTimePicker","openDateRangePicker","openMonthPicker","showCalendar","showYearPicker","showMonths","previousMonth","nextMonth","previousYear","nextYear","selectYear","dateFieldKeyboardInput","segmentYear","segmentMonth","segmentDay","segmentHour","segmentMinute","segmentSecond","segmentDayPeriod","segmentInvalid","rangeSeparator","validationBeforeMin","validationAfterMax","validationUnavailable","resolveDateComponentLabels","partial","formatSelectYear","labels","year","replace","String","VALIDATION_LABEL_KEYS","beforeMin","afterMax","unavailable","formatDateValidationMessage","reason","rules","options","message","bound","minValue","maxValue","undefined","dateStyle","SEGMENT_LABEL_KEYS","month","day","hour","minute","second","dayPeriod","getDateSegmentAccessibilityLabel","type","invalid","key"],"sourceRoot":"../../../../src","sources":["dates/labels/dateComponentLabels.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { compareDateIds } from '../ranges/compareDateIds';
|
|
4
|
+
/**
|
|
5
|
+
* Checks a complete wire date against `minValue`, `maxValue`, and `isDateUnavailable`.
|
|
6
|
+
*
|
|
7
|
+
* Bounds are inclusive and are checked before the predicate, so a date outside
|
|
8
|
+
* the range reports `beforeMin` / `afterMax` even when it is also unavailable.
|
|
9
|
+
*
|
|
10
|
+
* @param date - Wire date to check.
|
|
11
|
+
* @param rules - Bounds and unavailable-date predicate.
|
|
12
|
+
* @returns The first rule the date violates, or `undefined` when it is selectable.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* getDateValidationReason(dateId('2026-08-01'), { minValue: dateId('2026-08-10') }) // 'beforeMin'
|
|
16
|
+
*/
|
|
17
|
+
export function getDateValidationReason(date, rules) {
|
|
18
|
+
if (rules.minValue !== undefined && compareDateIds(date, rules.minValue) < 0) {
|
|
19
|
+
return 'beforeMin';
|
|
20
|
+
}
|
|
21
|
+
if (rules.maxValue !== undefined && compareDateIds(date, rules.maxValue) > 0) {
|
|
22
|
+
return 'afterMax';
|
|
23
|
+
}
|
|
24
|
+
if (rules.isDateUnavailable?.(date)) {
|
|
25
|
+
return 'unavailable';
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=getDateValidationReason.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["compareDateIds","getDateValidationReason","date","rules","minValue","undefined","maxValue","isDateUnavailable"],"sourceRoot":"../../../../src","sources":["dates/validation/getDateValidationReason.ts"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,0BAA0B;AAGzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACrCC,IAAY,EACZC,KAA0B,EACQ;EAClC,IAAIA,KAAK,CAACC,QAAQ,KAAKC,SAAS,IAAIL,cAAc,CAACE,IAAI,EAAEC,KAAK,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC5E,OAAO,WAAW;EACpB;EACA,IAAID,KAAK,CAACG,QAAQ,KAAKD,SAAS,IAAIL,cAAc,CAACE,IAAI,EAAEC,KAAK,CAACG,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC5E,OAAO,UAAU;EACnB;EACA,IAAIH,KAAK,CAACI,iBAAiB,GAAGL,IAAI,CAAC,EAAE;IACnC,OAAO,aAAa;EACtB;EACA,OAAOG,SAAS;AAClB","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -12,6 +12,8 @@ formatDateForDisplay, formatDateRangeForDisplay, formatDateTimeForDisplay, forma
|
|
|
12
12
|
compareDateIds, compareMonthIds, dateRangeAroundDay, dateRangeFromLastNDays, eachDateIdInRange, normalizeDateRange,
|
|
13
13
|
// Segmented field helpers
|
|
14
14
|
applyDateSegmentChange, formatDateSegment, getDateFieldSegments, getDateTimeFieldSegments, getDateTimeSegmentVisibility, getEmptyDateSegmentText, parseDateSegment,
|
|
15
|
+
// Validation
|
|
16
|
+
getDateValidationReason,
|
|
15
17
|
// Calendar / list copy
|
|
16
|
-
formatCalendarMonthYear, formatDateTimeListDateRow, formatDateTimeListHour, formatDateTimeListMinute, formatDateTimeListPeriod, formatMonthCalendarMonth, formatMonthCalendarYear, getCalendarWeekdayLabels, DEFAULT_DATE_COMPONENT_LABELS, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels } from './dates';
|
|
18
|
+
formatCalendarMonthYear, formatDateTimeListDateRow, formatDateTimeListHour, formatDateTimeListMinute, formatDateTimeListPeriod, formatMonthCalendarMonth, formatMonthCalendarYear, getCalendarWeekdayLabels, DEFAULT_DATE_COMPONENT_LABELS, formatDateValidationMessage, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels } from './dates';
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["formatNumber","clampDateParts","clampMonthParts","dateId","monthId","formatDateId","formatMonthId","isValidDateId","isValidDateParts","isValidMonthId","isValidMonthParts","parseDateId","parseMonthId","toMonthId","todayDateId","todayMonthId","clampDateTimeId","compareDateTimeIds","dateTimeId","formatDateTimeId","isLocaleHour12","isValidDateTimeId","nowDateTimeId","parseDateTimeId","formatDateForDisplay","formatDateRangeForDisplay","formatDateTimeForDisplay","formatMonthForDisplay","compareDateIds","compareMonthIds","dateRangeAroundDay","dateRangeFromLastNDays","eachDateIdInRange","normalizeDateRange","applyDateSegmentChange","formatDateSegment","getDateFieldSegments","getDateTimeFieldSegments","getDateTimeSegmentVisibility","getEmptyDateSegmentText","parseDateSegment","formatCalendarMonthYear","formatDateTimeListDateRow","formatDateTimeListHour","formatDateTimeListMinute","formatDateTimeListPeriod","formatMonthCalendarMonth","formatMonthCalendarYear","getCalendarWeekdayLabels","DEFAULT_DATE_COMPONENT_LABELS","formatSelectYear","getDateSegmentAccessibilityLabel","resolveDateComponentLabels"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAkC,gBAAgB;
|
|
1
|
+
{"version":3,"names":["formatNumber","clampDateParts","clampMonthParts","dateId","monthId","formatDateId","formatMonthId","isValidDateId","isValidDateParts","isValidMonthId","isValidMonthParts","parseDateId","parseMonthId","toMonthId","todayDateId","todayMonthId","clampDateTimeId","compareDateTimeIds","dateTimeId","formatDateTimeId","isLocaleHour12","isValidDateTimeId","nowDateTimeId","parseDateTimeId","formatDateForDisplay","formatDateRangeForDisplay","formatDateTimeForDisplay","formatMonthForDisplay","compareDateIds","compareMonthIds","dateRangeAroundDay","dateRangeFromLastNDays","eachDateIdInRange","normalizeDateRange","applyDateSegmentChange","formatDateSegment","getDateFieldSegments","getDateTimeFieldSegments","getDateTimeSegmentVisibility","getEmptyDateSegmentText","parseDateSegment","getDateValidationReason","formatCalendarMonthYear","formatDateTimeListDateRow","formatDateTimeListHour","formatDateTimeListMinute","formatDateTimeListPeriod","formatMonthCalendarMonth","formatMonthCalendarYear","getCalendarWeekdayLabels","DEFAULT_DATE_COMPONENT_LABELS","formatDateValidationMessage","formatSelectYear","getDateSegmentAccessibilityLabel","resolveDateComponentLabels"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAkC,gBAAgB;AAsBvE;AACE;AACAC,cAAc,EACdC,eAAe,EACfC,MAAM,EACNC,OAAO,EACPC,YAAY,EACZC,aAAa,EACbC,aAAa,EACbC,gBAAgB,EAChBC,cAAc,EACdC,iBAAiB,EACjBC,WAAW,EACXC,YAAY,EACZC,SAAS,EACTC,WAAW,EACXC,YAAY;AACZ;AACAC,eAAe,EACfC,kBAAkB,EAClBC,UAAU,EACVC,gBAAgB,EAChBC,cAAc,EACdC,iBAAiB,EACjBC,aAAa,EACbC,eAAe;AACf;AACAC,oBAAoB,EACpBC,yBAAyB,EACzBC,wBAAwB,EACxBC,qBAAqB;AACrB;AACAC,cAAc,EACdC,eAAe,EACfC,kBAAkB,EAClBC,sBAAsB,EACtBC,iBAAiB,EACjBC,kBAAkB;AAClB;AACAC,sBAAsB,EACtBC,iBAAiB,EACjBC,oBAAoB,EACpBC,wBAAwB,EACxBC,4BAA4B,EAC5BC,uBAAuB,EACvBC,gBAAgB;AAChB;AACAC,uBAAuB;AACvB;AACAC,uBAAuB,EACvBC,yBAAyB,EACzBC,sBAAsB,EACtBC,wBAAwB,EACxBC,wBAAwB,EACxBC,wBAAwB,EACxBC,uBAAuB,EACvBC,wBAAwB,EACxBC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,gBAAgB,EAChBC,gCAAgC,EAChCC,0BAA0B,QACrB,SAAS","ignoreList":[]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Wire ids (`DateId`, `MonthId`, `DateTimeId`) are fixed-format strings for state and APIs.
|
|
5
5
|
* Display helpers return locale-dependent strings for UI labels — never store those in form state.
|
|
6
6
|
*/
|
|
7
|
-
export type { DateFieldMode, DateFormatOptions, DateId, DateParts, DateRangeDisplayOptions, DateSegment, DateSegmentType, DateTimeGranularity, DateTimeId, DateTimeParts, FormatDateDisplayOptions, FormatDateTimeDisplayOptions, MonthId, MonthParts, TimeParts, } from './types';
|
|
7
|
+
export type { DateFieldMode, DateFormatOptions, DateId, DateParts, DateRangeDisplayOptions, DateSegment, DateSegmentType, DateTimeGranularity, DateTimeId, DateTimeParts, DateValidationReason, DateValidationRules, FormatDateDisplayOptions, FormatDateTimeDisplayOptions, MonthId, MonthParts, TimeParts, } from './types';
|
|
8
8
|
export { clampDateParts } from './wire/clampDateParts';
|
|
9
9
|
export { clampMonthParts } from './wire/clampMonthParts';
|
|
10
10
|
export { dateId } from './wire/dateId';
|
|
@@ -48,11 +48,12 @@ export { getDateTimeFieldSegments } from './segments/getDateTimeFieldSegments';
|
|
|
48
48
|
export { getDateTimeSegmentVisibility } from './segments/getDateTimeSegmentVisibility';
|
|
49
49
|
export { getEmptyDateSegmentText } from './segments/getEmptyDateSegmentText';
|
|
50
50
|
export { parseDateSegment } from './segments/parseDateSegment';
|
|
51
|
+
export { getDateValidationReason } from './validation/getDateValidationReason';
|
|
51
52
|
export { formatCalendarMonthYear } from './calendar/formatCalendarMonthYear';
|
|
52
53
|
export { formatDateTimeListDateRow } from './calendar/formatDateTimeListDateRow';
|
|
53
54
|
export { formatMonthCalendarMonth } from './calendar/formatMonthCalendarMonth';
|
|
54
55
|
export { formatMonthCalendarYear } from './calendar/formatMonthCalendarYear';
|
|
55
56
|
export { getCalendarWeekdayLabels } from './calendar/getCalendarWeekdayLabels';
|
|
56
57
|
export type { DateComponentLabels } from './labels/dateComponentLabels';
|
|
57
|
-
export { DEFAULT_DATE_COMPONENT_LABELS, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels, } from './labels/dateComponentLabels';
|
|
58
|
+
export { DEFAULT_DATE_COMPONENT_LABELS, formatDateValidationMessage, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels, } from './labels/dateComponentLabels';
|
|
58
59
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dates/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dates/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DateSegmentType } from '../types';
|
|
1
|
+
import type { DateSegmentType, DateValidationReason, DateValidationRules, FormatDateDisplayOptions } from '../types';
|
|
2
2
|
/** Overridable UI copy for date pickers, calendars, and segmented date fields. */
|
|
3
3
|
export interface DateComponentLabels {
|
|
4
4
|
openDatePicker: string;
|
|
@@ -22,10 +22,39 @@ export interface DateComponentLabels {
|
|
|
22
22
|
segmentMinute: string;
|
|
23
23
|
segmentSecond: string;
|
|
24
24
|
segmentDayPeriod: string;
|
|
25
|
+
/**
|
|
26
|
+
* Native accessible name of a segment while the field is invalid — iOS and Android have no
|
|
27
|
+
* equivalent of `aria-invalid`. Use `{segment}` as the segment label placeholder.
|
|
28
|
+
*/
|
|
29
|
+
segmentInvalid: string;
|
|
25
30
|
rangeSeparator: string;
|
|
31
|
+
/** Use `{date}` as the `minValue` placeholder. */
|
|
32
|
+
validationBeforeMin: string;
|
|
33
|
+
/** Use `{date}` as the `maxValue` placeholder. */
|
|
34
|
+
validationAfterMax: string;
|
|
35
|
+
validationUnavailable: string;
|
|
26
36
|
}
|
|
27
37
|
export declare const DEFAULT_DATE_COMPONENT_LABELS: DateComponentLabels;
|
|
28
38
|
export declare function resolveDateComponentLabels(partial?: Partial<DateComponentLabels>): DateComponentLabels;
|
|
29
39
|
export declare function formatSelectYear(labels: DateComponentLabels, year: number): string;
|
|
30
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Resolves the user-facing message for a {@link DateValidationReason}.
|
|
42
|
+
*
|
|
43
|
+
* `{date}` in the min / max messages is replaced with the bound, formatted for display
|
|
44
|
+
* with `options.locale` and `options.dateStyle` (defaults: `en-US`, `medium`). `DatePicker`
|
|
45
|
+
* already formats this message with its own `labels` and `locale` (see `onValidationChange`
|
|
46
|
+
* and `Field.Error`); call this directly only outside a picker, and pass the same `locale`.
|
|
47
|
+
*
|
|
48
|
+
* @param labels - Resolved labels (see `resolveDateComponentLabels`).
|
|
49
|
+
* @param reason - Reason returned by `getDateValidationReason` or `onValidationChange`.
|
|
50
|
+
* @param rules - The bounds the reason was computed against.
|
|
51
|
+
* @param options - Display options for the `{date}` placeholder.
|
|
52
|
+
* @returns The message to render in `Field.Error`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatDateValidationMessage(labels: DateComponentLabels, reason: DateValidationReason, rules: Pick<DateValidationRules, 'minValue' | 'maxValue'>, options?: FormatDateDisplayOptions): string;
|
|
55
|
+
/**
|
|
56
|
+
* @param invalid - Wraps the label in `labels.segmentInvalid`, for native platforms where
|
|
57
|
+
* `aria-invalid` is not announced.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getDateSegmentAccessibilityLabel(type: DateSegmentType, labels: DateComponentLabels, invalid?: boolean): string | undefined;
|
|
31
60
|
//# sourceMappingURL=dateComponentLabels.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dateComponentLabels.d.ts","sourceRoot":"","sources":["../../../../src/dates/labels/dateComponentLabels.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dateComponentLabels.d.ts","sourceRoot":"","sources":["../../../../src/dates/labels/dateComponentLabels.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,UAAU,CAAC;AAElB,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,6BAA6B,EAAE,mBA0B3C,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACrC,mBAAmB,CAErB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAElF;AAQD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,UAAU,CAAC,EACzD,OAAO,CAAC,EAAE,wBAAwB,GACjC,MAAM,CAWR;AAYD;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,UAAQ,GACd,MAAM,GAAG,SAAS,CAMpB"}
|
|
@@ -39,6 +39,17 @@ export interface TimeParts {
|
|
|
39
39
|
export interface DateTimeParts extends DateParts, TimeParts {
|
|
40
40
|
}
|
|
41
41
|
export type DateFieldMode = 'date' | 'month';
|
|
42
|
+
/** Why a complete date fails its selection rules. */
|
|
43
|
+
export type DateValidationReason = 'beforeMin' | 'afterMax' | 'unavailable';
|
|
44
|
+
/** Selection rules shared by `Calendar`, `DatePicker`, and `getDateValidationReason`. */
|
|
45
|
+
export interface DateValidationRules {
|
|
46
|
+
/** Earliest valid date (inclusive). */
|
|
47
|
+
minValue?: DateId;
|
|
48
|
+
/** Latest valid date (inclusive). */
|
|
49
|
+
maxValue?: DateId;
|
|
50
|
+
/** Returns `true` for dates that cannot be selected, such as weekends or holidays. */
|
|
51
|
+
isDateUnavailable?: (date: DateId) => boolean;
|
|
52
|
+
}
|
|
42
53
|
export type DateTimeGranularity = 'day' | 'hour' | 'minute' | 'second';
|
|
43
54
|
export type DateSegmentType = 'era' | 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'dayPeriod' | 'literal';
|
|
44
55
|
export interface DateSegment {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/dates/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;AAC7D,uFAAuF;AACvF,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,oGAAoG;AACpG,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,EAAE,SAAS;CAAG;AAE9D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,4BAA6B,SAAQ,iBAAiB;IACrE,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/dates/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;AAC7D,uFAAuF;AACvF,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,oGAAoG;AACpG,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,EAAE,SAAS;CAAG;AAE9D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C,qDAAqD;AACrD,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;AAE5E,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/C;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,4BAA6B,SAAQ,iBAAiB;IACrE,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DateId, DateValidationReason, DateValidationRules } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a complete wire date against `minValue`, `maxValue`, and `isDateUnavailable`.
|
|
4
|
+
*
|
|
5
|
+
* Bounds are inclusive and are checked before the predicate, so a date outside
|
|
6
|
+
* the range reports `beforeMin` / `afterMax` even when it is also unavailable.
|
|
7
|
+
*
|
|
8
|
+
* @param date - Wire date to check.
|
|
9
|
+
* @param rules - Bounds and unavailable-date predicate.
|
|
10
|
+
* @returns The first rule the date violates, or `undefined` when it is selectable.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* getDateValidationReason(dateId('2026-08-01'), { minValue: dateId('2026-08-10') }) // 'beforeMin'
|
|
14
|
+
*/
|
|
15
|
+
export declare function getDateValidationReason(date: DateId, rules: DateValidationRules): DateValidationReason | undefined;
|
|
16
|
+
//# sourceMappingURL=getDateValidationReason.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDateValidationReason.d.ts","sourceRoot":"","sources":["../../../../src/dates/validation/getDateValidationReason.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAElF;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,mBAAmB,GACzB,oBAAoB,GAAG,SAAS,CAWlC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { formatNumber, type FormatNumberOptions } from './formatNumber';
|
|
2
|
-
export type { DateFieldMode, DateFormatOptions, DateId, DateParts, DateRangeDisplayOptions, DateSegment, DateSegmentType, DateTimeGranularity, DateTimeId, DateTimeParts, FormatDateDisplayOptions, FormatDateTimeDisplayOptions, MonthId, MonthParts, TimeParts, } from './dates/types';
|
|
3
|
-
export { clampDateParts, clampMonthParts, dateId, monthId, formatDateId, formatMonthId, isValidDateId, isValidDateParts, isValidMonthId, isValidMonthParts, parseDateId, parseMonthId, toMonthId, todayDateId, todayMonthId, clampDateTimeId, compareDateTimeIds, dateTimeId, formatDateTimeId, isLocaleHour12, isValidDateTimeId, nowDateTimeId, parseDateTimeId, formatDateForDisplay, formatDateRangeForDisplay, formatDateTimeForDisplay, formatMonthForDisplay, compareDateIds, compareMonthIds, dateRangeAroundDay, dateRangeFromLastNDays, eachDateIdInRange, normalizeDateRange, applyDateSegmentChange, formatDateSegment, getDateFieldSegments, getDateTimeFieldSegments, getDateTimeSegmentVisibility, getEmptyDateSegmentText, parseDateSegment, formatCalendarMonthYear, formatDateTimeListDateRow, formatDateTimeListHour, formatDateTimeListMinute, formatDateTimeListPeriod, formatMonthCalendarMonth, formatMonthCalendarYear, getCalendarWeekdayLabels, DEFAULT_DATE_COMPONENT_LABELS, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels, } from './dates';
|
|
2
|
+
export type { DateFieldMode, DateFormatOptions, DateId, DateParts, DateRangeDisplayOptions, DateSegment, DateSegmentType, DateTimeGranularity, DateTimeId, DateTimeParts, DateValidationReason, DateValidationRules, FormatDateDisplayOptions, FormatDateTimeDisplayOptions, MonthId, MonthParts, TimeParts, } from './dates/types';
|
|
3
|
+
export { clampDateParts, clampMonthParts, dateId, monthId, formatDateId, formatMonthId, isValidDateId, isValidDateParts, isValidMonthId, isValidMonthParts, parseDateId, parseMonthId, toMonthId, todayDateId, todayMonthId, clampDateTimeId, compareDateTimeIds, dateTimeId, formatDateTimeId, isLocaleHour12, isValidDateTimeId, nowDateTimeId, parseDateTimeId, formatDateForDisplay, formatDateRangeForDisplay, formatDateTimeForDisplay, formatMonthForDisplay, compareDateIds, compareMonthIds, dateRangeAroundDay, dateRangeFromLastNDays, eachDateIdInRange, normalizeDateRange, applyDateSegmentChange, formatDateSegment, getDateFieldSegments, getDateTimeFieldSegments, getDateTimeSegmentVisibility, getEmptyDateSegmentText, parseDateSegment, getDateValidationReason, formatCalendarMonthYear, formatDateTimeListDateRow, formatDateTimeListHour, formatDateTimeListMinute, formatDateTimeListPeriod, formatMonthCalendarMonth, formatMonthCalendarYear, getCalendarWeekdayLabels, DEFAULT_DATE_COMPONENT_LABELS, formatDateValidationMessage, formatSelectYear, getDateSegmentAccessibilityLabel, resolveDateComponentLabels, } from './dates';
|
|
4
4
|
export type { DateComponentLabels } from './dates';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAExE,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,MAAM,EACN,SAAS,EACT,uBAAuB,EACvB,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,wBAAwB,EACxB,4BAA4B,EAC5B,OAAO,EACP,UAAU,EACV,SAAS,GACV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,cAAc,EACd,eAAe,EACf,MAAM,EACN,OAAO,EACP,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EAEZ,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,eAAe,EAEf,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EAErB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAElB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,gBAAgB,EAEhB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,6BAA6B,EAC7B,gBAAgB,EAChB,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAExE,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,MAAM,EACN,SAAS,EACT,uBAAuB,EACvB,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,4BAA4B,EAC5B,OAAO,EACP,UAAU,EACV,SAAS,GACV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,cAAc,EACd,eAAe,EACf,MAAM,EACN,OAAO,EACP,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EAEZ,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,eAAe,EAEf,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EAErB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAElB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,gBAAgB,EAEhB,uBAAuB,EAEvB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,gBAAgB,EAChB,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { DateId } from '../dates/types';
|
|
1
2
|
import {
|
|
2
3
|
DEFAULT_DATE_COMPONENT_LABELS,
|
|
4
|
+
formatDateValidationMessage,
|
|
3
5
|
formatSelectYear,
|
|
4
6
|
getDateSegmentAccessibilityLabel,
|
|
5
7
|
resolveDateComponentLabels,
|
|
@@ -22,4 +24,57 @@ describe('dateComponentLabels', () => {
|
|
|
22
24
|
expect(getDateSegmentAccessibilityLabel('month', labels)).toBe('Month');
|
|
23
25
|
expect(getDateSegmentAccessibilityLabel('literal', labels)).toBeUndefined();
|
|
24
26
|
});
|
|
27
|
+
|
|
28
|
+
it('wraps segment labels in segmentInvalid when invalid', () => {
|
|
29
|
+
expect(getDateSegmentAccessibilityLabel('day', resolveDateComponentLabels(), true)).toBe(
|
|
30
|
+
'Day, invalid',
|
|
31
|
+
);
|
|
32
|
+
const labels = resolveDateComponentLabels({
|
|
33
|
+
segmentDay: 'Jour',
|
|
34
|
+
segmentInvalid: '{segment} invalide',
|
|
35
|
+
});
|
|
36
|
+
expect(getDateSegmentAccessibilityLabel('day', labels, true)).toBe('Jour invalide');
|
|
37
|
+
expect(getDateSegmentAccessibilityLabel('literal', labels, true)).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('formatDateValidationMessage', () => {
|
|
41
|
+
const rules = { minValue: '2026-08-10' as DateId, maxValue: '2026-08-20' as DateId };
|
|
42
|
+
|
|
43
|
+
it('fills the {date} placeholder with the formatted bound', () => {
|
|
44
|
+
const labels = resolveDateComponentLabels();
|
|
45
|
+
expect(formatDateValidationMessage(labels, 'beforeMin', rules)).toBe(
|
|
46
|
+
'Select a date on or after Aug 10, 2026',
|
|
47
|
+
);
|
|
48
|
+
expect(formatDateValidationMessage(labels, 'afterMax', rules)).toBe(
|
|
49
|
+
'Select a date on or before Aug 20, 2026',
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('formats the bound in options.locale', () => {
|
|
54
|
+
const labels = resolveDateComponentLabels({ validationBeforeMin: 'À partir du {date}' });
|
|
55
|
+
expect(formatDateValidationMessage(labels, 'beforeMin', rules, { locale: 'fr-FR' })).toBe(
|
|
56
|
+
'À partir du 10 août 2026',
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('returns the unavailable message as-is', () => {
|
|
61
|
+
const labels = resolveDateComponentLabels();
|
|
62
|
+
expect(formatDateValidationMessage(labels, 'unavailable', rules)).toBe(
|
|
63
|
+
'This date is unavailable',
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('uses label overrides and display options', () => {
|
|
68
|
+
const labels = resolveDateComponentLabels({
|
|
69
|
+
validationBeforeMin: 'Pick {date} or later',
|
|
70
|
+
validationUnavailable: 'Payments do not process on this date',
|
|
71
|
+
});
|
|
72
|
+
expect(formatDateValidationMessage(labels, 'beforeMin', rules, { dateStyle: 'short' })).toBe(
|
|
73
|
+
'Pick 8/10/26 or later',
|
|
74
|
+
);
|
|
75
|
+
expect(formatDateValidationMessage(labels, 'unavailable', rules)).toBe(
|
|
76
|
+
'Payments do not process on this date',
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
25
80
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getDateValidationReason } from '../dates/validation/getDateValidationReason';
|
|
2
|
+
import type { DateId } from '../dates/types';
|
|
3
|
+
|
|
4
|
+
const isWeekend = (date: DateId) => {
|
|
5
|
+
const day = new Date(`${date}T00:00:00`).getDay();
|
|
6
|
+
return day === 0 || day === 6;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
describe('getDateValidationReason', () => {
|
|
10
|
+
const rules = {
|
|
11
|
+
minValue: '2026-08-10' as DateId,
|
|
12
|
+
maxValue: '2026-08-20' as DateId,
|
|
13
|
+
isDateUnavailable: isWeekend,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
it('returns beforeMin for a date before minValue', () => {
|
|
17
|
+
expect(getDateValidationReason('2026-08-03' as DateId, rules)).toBe('beforeMin');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('returns afterMax for a date after maxValue', () => {
|
|
21
|
+
expect(getDateValidationReason('2026-08-24' as DateId, rules)).toBe('afterMax');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns unavailable when the predicate returns true', () => {
|
|
25
|
+
expect(getDateValidationReason('2026-08-15' as DateId, rules)).toBe('unavailable');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('returns undefined for a selectable date', () => {
|
|
29
|
+
expect(getDateValidationReason('2026-08-14' as DateId, rules)).toBeUndefined();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('treats bounds as inclusive', () => {
|
|
33
|
+
expect(getDateValidationReason('2026-08-10' as DateId, rules)).toBeUndefined();
|
|
34
|
+
expect(getDateValidationReason('2026-08-20' as DateId, rules)).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('reports bounds before the predicate when both apply', () => {
|
|
38
|
+
expect(getDateValidationReason('2026-08-08' as DateId, rules)).toBe('beforeMin');
|
|
39
|
+
expect(getDateValidationReason('2026-08-22' as DateId, rules)).toBe('afterMax');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('returns undefined when no rules are set', () => {
|
|
43
|
+
expect(getDateValidationReason('2026-08-15' as DateId, {})).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
});
|
package/src/dates/index.ts
CHANGED
|
@@ -16,6 +16,8 @@ export type {
|
|
|
16
16
|
DateTimeGranularity,
|
|
17
17
|
DateTimeId,
|
|
18
18
|
DateTimeParts,
|
|
19
|
+
DateValidationReason,
|
|
20
|
+
DateValidationRules,
|
|
19
21
|
FormatDateDisplayOptions,
|
|
20
22
|
FormatDateTimeDisplayOptions,
|
|
21
23
|
MonthId,
|
|
@@ -71,6 +73,8 @@ export { getDateTimeSegmentVisibility } from './segments/getDateTimeSegmentVisib
|
|
|
71
73
|
export { getEmptyDateSegmentText } from './segments/getEmptyDateSegmentText';
|
|
72
74
|
export { parseDateSegment } from './segments/parseDateSegment';
|
|
73
75
|
|
|
76
|
+
export { getDateValidationReason } from './validation/getDateValidationReason';
|
|
77
|
+
|
|
74
78
|
export { formatCalendarMonthYear } from './calendar/formatCalendarMonthYear';
|
|
75
79
|
export { formatDateTimeListDateRow } from './calendar/formatDateTimeListDateRow';
|
|
76
80
|
export { formatMonthCalendarMonth } from './calendar/formatMonthCalendarMonth';
|
|
@@ -80,6 +84,7 @@ export { getCalendarWeekdayLabels } from './calendar/getCalendarWeekdayLabels';
|
|
|
80
84
|
export type { DateComponentLabels } from './labels/dateComponentLabels';
|
|
81
85
|
export {
|
|
82
86
|
DEFAULT_DATE_COMPONENT_LABELS,
|
|
87
|
+
formatDateValidationMessage,
|
|
83
88
|
formatSelectYear,
|
|
84
89
|
getDateSegmentAccessibilityLabel,
|
|
85
90
|
resolveDateComponentLabels,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { formatDateForDisplay } from '../display/formatDateForDisplay';
|
|
2
|
+
import type {
|
|
3
|
+
DateSegmentType,
|
|
4
|
+
DateValidationReason,
|
|
5
|
+
DateValidationRules,
|
|
6
|
+
FormatDateDisplayOptions,
|
|
7
|
+
} from '../types';
|
|
2
8
|
|
|
3
9
|
/** Overridable UI copy for date pickers, calendars, and segmented date fields. */
|
|
4
10
|
export interface DateComponentLabels {
|
|
@@ -23,7 +29,17 @@ export interface DateComponentLabels {
|
|
|
23
29
|
segmentMinute: string;
|
|
24
30
|
segmentSecond: string;
|
|
25
31
|
segmentDayPeriod: string;
|
|
32
|
+
/**
|
|
33
|
+
* Native accessible name of a segment while the field is invalid — iOS and Android have no
|
|
34
|
+
* equivalent of `aria-invalid`. Use `{segment}` as the segment label placeholder.
|
|
35
|
+
*/
|
|
36
|
+
segmentInvalid: string;
|
|
26
37
|
rangeSeparator: string;
|
|
38
|
+
/** Use `{date}` as the `minValue` placeholder. */
|
|
39
|
+
validationBeforeMin: string;
|
|
40
|
+
/** Use `{date}` as the `maxValue` placeholder. */
|
|
41
|
+
validationAfterMax: string;
|
|
42
|
+
validationUnavailable: string;
|
|
27
43
|
}
|
|
28
44
|
|
|
29
45
|
export const DEFAULT_DATE_COMPONENT_LABELS: DateComponentLabels = {
|
|
@@ -47,7 +63,11 @@ export const DEFAULT_DATE_COMPONENT_LABELS: DateComponentLabels = {
|
|
|
47
63
|
segmentMinute: 'Minute',
|
|
48
64
|
segmentSecond: 'Second',
|
|
49
65
|
segmentDayPeriod: 'AM/PM',
|
|
66
|
+
segmentInvalid: '{segment}, invalid',
|
|
50
67
|
rangeSeparator: '–',
|
|
68
|
+
validationBeforeMin: 'Select a date on or after {date}',
|
|
69
|
+
validationAfterMax: 'Select a date on or before {date}',
|
|
70
|
+
validationUnavailable: 'This date is unavailable',
|
|
51
71
|
};
|
|
52
72
|
|
|
53
73
|
export function resolveDateComponentLabels(
|
|
@@ -60,6 +80,44 @@ export function formatSelectYear(labels: DateComponentLabels, year: number): str
|
|
|
60
80
|
return labels.selectYear.replace('{year}', String(year));
|
|
61
81
|
}
|
|
62
82
|
|
|
83
|
+
const VALIDATION_LABEL_KEYS: Record<DateValidationReason, keyof DateComponentLabels> = {
|
|
84
|
+
beforeMin: 'validationBeforeMin',
|
|
85
|
+
afterMax: 'validationAfterMax',
|
|
86
|
+
unavailable: 'validationUnavailable',
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Resolves the user-facing message for a {@link DateValidationReason}.
|
|
91
|
+
*
|
|
92
|
+
* `{date}` in the min / max messages is replaced with the bound, formatted for display
|
|
93
|
+
* with `options.locale` and `options.dateStyle` (defaults: `en-US`, `medium`). `DatePicker`
|
|
94
|
+
* already formats this message with its own `labels` and `locale` (see `onValidationChange`
|
|
95
|
+
* and `Field.Error`); call this directly only outside a picker, and pass the same `locale`.
|
|
96
|
+
*
|
|
97
|
+
* @param labels - Resolved labels (see `resolveDateComponentLabels`).
|
|
98
|
+
* @param reason - Reason returned by `getDateValidationReason` or `onValidationChange`.
|
|
99
|
+
* @param rules - The bounds the reason was computed against.
|
|
100
|
+
* @param options - Display options for the `{date}` placeholder.
|
|
101
|
+
* @returns The message to render in `Field.Error`.
|
|
102
|
+
*/
|
|
103
|
+
export function formatDateValidationMessage(
|
|
104
|
+
labels: DateComponentLabels,
|
|
105
|
+
reason: DateValidationReason,
|
|
106
|
+
rules: Pick<DateValidationRules, 'minValue' | 'maxValue'>,
|
|
107
|
+
options?: FormatDateDisplayOptions,
|
|
108
|
+
): string {
|
|
109
|
+
const message = labels[VALIDATION_LABEL_KEYS[reason]];
|
|
110
|
+
const bound =
|
|
111
|
+
reason === 'beforeMin' ? rules.minValue : reason === 'afterMax' ? rules.maxValue : undefined;
|
|
112
|
+
if (bound === undefined) {
|
|
113
|
+
return message;
|
|
114
|
+
}
|
|
115
|
+
return message.replace(
|
|
116
|
+
'{date}',
|
|
117
|
+
formatDateForDisplay(bound, { dateStyle: 'medium', ...options }),
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
63
121
|
const SEGMENT_LABEL_KEYS: Partial<Record<DateSegmentType, keyof DateComponentLabels>> = {
|
|
64
122
|
year: 'segmentYear',
|
|
65
123
|
month: 'segmentMonth',
|
|
@@ -70,10 +128,18 @@ const SEGMENT_LABEL_KEYS: Partial<Record<DateSegmentType, keyof DateComponentLab
|
|
|
70
128
|
dayPeriod: 'segmentDayPeriod',
|
|
71
129
|
};
|
|
72
130
|
|
|
131
|
+
/**
|
|
132
|
+
* @param invalid - Wraps the label in `labels.segmentInvalid`, for native platforms where
|
|
133
|
+
* `aria-invalid` is not announced.
|
|
134
|
+
*/
|
|
73
135
|
export function getDateSegmentAccessibilityLabel(
|
|
74
136
|
type: DateSegmentType,
|
|
75
137
|
labels: DateComponentLabels,
|
|
138
|
+
invalid = false,
|
|
76
139
|
): string | undefined {
|
|
77
140
|
const key = SEGMENT_LABEL_KEYS[type];
|
|
78
|
-
|
|
141
|
+
if (!key) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return invalid ? labels.segmentInvalid.replace('{segment}', labels[key]) : labels[key];
|
|
79
145
|
}
|
package/src/dates/types.ts
CHANGED
|
@@ -39,6 +39,19 @@ export interface DateTimeParts extends DateParts, TimeParts {}
|
|
|
39
39
|
|
|
40
40
|
export type DateFieldMode = 'date' | 'month';
|
|
41
41
|
|
|
42
|
+
/** Why a complete date fails its selection rules. */
|
|
43
|
+
export type DateValidationReason = 'beforeMin' | 'afterMax' | 'unavailable';
|
|
44
|
+
|
|
45
|
+
/** Selection rules shared by `Calendar`, `DatePicker`, and `getDateValidationReason`. */
|
|
46
|
+
export interface DateValidationRules {
|
|
47
|
+
/** Earliest valid date (inclusive). */
|
|
48
|
+
minValue?: DateId;
|
|
49
|
+
/** Latest valid date (inclusive). */
|
|
50
|
+
maxValue?: DateId;
|
|
51
|
+
/** Returns `true` for dates that cannot be selected, such as weekends or holidays. */
|
|
52
|
+
isDateUnavailable?: (date: DateId) => boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
export type DateTimeGranularity = 'day' | 'hour' | 'minute' | 'second';
|
|
43
56
|
|
|
44
57
|
export type DateSegmentType =
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { compareDateIds } from '../ranges/compareDateIds';
|
|
2
|
+
import type { DateId, DateValidationReason, DateValidationRules } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks a complete wire date against `minValue`, `maxValue`, and `isDateUnavailable`.
|
|
6
|
+
*
|
|
7
|
+
* Bounds are inclusive and are checked before the predicate, so a date outside
|
|
8
|
+
* the range reports `beforeMin` / `afterMax` even when it is also unavailable.
|
|
9
|
+
*
|
|
10
|
+
* @param date - Wire date to check.
|
|
11
|
+
* @param rules - Bounds and unavailable-date predicate.
|
|
12
|
+
* @returns The first rule the date violates, or `undefined` when it is selectable.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* getDateValidationReason(dateId('2026-08-01'), { minValue: dateId('2026-08-10') }) // 'beforeMin'
|
|
16
|
+
*/
|
|
17
|
+
export function getDateValidationReason(
|
|
18
|
+
date: DateId,
|
|
19
|
+
rules: DateValidationRules,
|
|
20
|
+
): DateValidationReason | undefined {
|
|
21
|
+
if (rules.minValue !== undefined && compareDateIds(date, rules.minValue) < 0) {
|
|
22
|
+
return 'beforeMin';
|
|
23
|
+
}
|
|
24
|
+
if (rules.maxValue !== undefined && compareDateIds(date, rules.maxValue) > 0) {
|
|
25
|
+
return 'afterMax';
|
|
26
|
+
}
|
|
27
|
+
if (rules.isDateUnavailable?.(date)) {
|
|
28
|
+
return 'unavailable';
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,8 @@ export type {
|
|
|
11
11
|
DateTimeGranularity,
|
|
12
12
|
DateTimeId,
|
|
13
13
|
DateTimeParts,
|
|
14
|
+
DateValidationReason,
|
|
15
|
+
DateValidationRules,
|
|
14
16
|
FormatDateDisplayOptions,
|
|
15
17
|
FormatDateTimeDisplayOptions,
|
|
16
18
|
MonthId,
|
|
@@ -64,6 +66,8 @@ export {
|
|
|
64
66
|
getDateTimeSegmentVisibility,
|
|
65
67
|
getEmptyDateSegmentText,
|
|
66
68
|
parseDateSegment,
|
|
69
|
+
// Validation
|
|
70
|
+
getDateValidationReason,
|
|
67
71
|
// Calendar / list copy
|
|
68
72
|
formatCalendarMonthYear,
|
|
69
73
|
formatDateTimeListDateRow,
|
|
@@ -74,6 +78,7 @@ export {
|
|
|
74
78
|
formatMonthCalendarYear,
|
|
75
79
|
getCalendarWeekdayLabels,
|
|
76
80
|
DEFAULT_DATE_COMPONENT_LABELS,
|
|
81
|
+
formatDateValidationMessage,
|
|
77
82
|
formatSelectYear,
|
|
78
83
|
getDateSegmentAccessibilityLabel,
|
|
79
84
|
resolveDateComponentLabels,
|