@tylertech/forge 3.9.1 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +183 -25
- package/dist/badge/forge-badge.css +1 -1
- package/dist/forge.css +0 -1
- package/dist/lib.js +22 -22
- package/dist/lib.js.map +3 -3
- package/dist/table/forge-table.css +0 -1
- package/dist/vscode.html-custom-data.json +20 -0
- package/esm/autocomplete/autocomplete-core.js +9 -12
- package/esm/autocomplete/autocomplete-utils.js +3 -2
- package/esm/badge/badge.js +1 -1
- package/esm/button/base/base-button-adapter.js +6 -5
- package/esm/button/base/base-button-constants.d.ts +2 -2
- package/esm/button-area/button-area-adapter.d.ts +0 -2
- package/esm/button-area/button-area-adapter.js +5 -3
- package/esm/button-area/button-area-core.js +0 -1
- package/esm/button-area/button-area.js +1 -1
- package/esm/button-toggle/button-toggle-group/button-toggle-group-core.js +0 -1
- package/esm/calendar/calendar-core.js +6 -4
- package/esm/calendar/calendar-dropdown/calendar-dropdown.js +1 -1
- package/esm/calendar/calendar-utils.js +1 -3
- package/esm/calendar/calendar.js +1 -1
- package/esm/color-picker/color-picker-core.js +2 -2
- package/esm/core/configuration/global-configuration.js +0 -1
- package/esm/core/mask/date-input-mask.js +18 -1
- package/esm/core/mixins/form/with-form-associated.js +6 -2
- package/esm/core/utils/a11y-utils.d.ts +2 -2
- package/esm/core/utils/date-utils.d.ts +14 -5
- package/esm/core/utils/date-utils.js +229 -70
- package/esm/core/utils/dismissible-stack.js +0 -1
- package/esm/core/utils/feature-detection.js +2 -2
- package/esm/date-picker/base/base-date-picker-adapter.d.ts +2 -1
- package/esm/date-picker/base/base-date-picker-adapter.js +4 -0
- package/esm/date-picker/base/base-date-picker-constants.d.ts +19 -4
- package/esm/date-picker/base/base-date-picker-constants.js +20 -1
- package/esm/date-picker/base/base-date-picker-core.d.ts +11 -3
- package/esm/date-picker/base/base-date-picker-core.js +70 -17
- package/esm/date-picker/base/base-date-picker-utils.d.ts +2 -1
- package/esm/date-picker/base/base-date-picker.d.ts +10 -2
- package/esm/date-picker/base/base-date-picker.js +17 -1
- package/esm/date-picker/date-picker-adapter.js +1 -1
- package/esm/date-picker/date-picker-core.js +3 -2
- package/esm/date-range-picker/date-range-picker-adapter.d.ts +2 -1
- package/esm/date-range-picker/date-range-picker-adapter.js +1 -1
- package/esm/date-range-picker/date-range-picker-core.d.ts +1 -0
- package/esm/date-range-picker/date-range-picker-core.js +18 -9
- package/esm/deprecated/icon-button/deprecated-icon-button-component-delegate.js +2 -1
- package/esm/dialog/dialog.js +1 -1
- package/esm/expansion-panel/expansion-panel-core.d.ts +4 -0
- package/esm/expansion-panel/expansion-panel-core.js +19 -11
- package/esm/field/field-core.js +2 -1
- package/esm/field/field.js +1 -1
- package/esm/file-picker/file-picker-core.js +1 -3
- package/esm/floating-action-button/floating-action-button-adapter.d.ts +0 -4
- package/esm/floating-action-button/floating-action-button-adapter.js +3 -24
- package/esm/floating-action-button/floating-action-button-component-delegate.js +2 -1
- package/esm/floating-action-button/floating-action-button-core.d.ts +0 -1
- package/esm/floating-action-button/floating-action-button-core.js +0 -3
- package/esm/floating-action-button/floating-action-button.d.ts +0 -1
- package/esm/floating-action-button/floating-action-button.js +0 -3
- package/esm/icon/icon-core.js +1 -1
- package/esm/icon/icon-registry.js +1 -1
- package/esm/icon-button/icon-button-component-delegate.js +2 -1
- package/esm/label/label-aware.js +1 -3
- package/esm/list/list/list.js +1 -1
- package/esm/list/list-item/list-item.js +1 -1
- package/esm/list-dropdown/list-dropdown-core.js +4 -2
- package/esm/list-dropdown/list-dropdown-utils.js +5 -2
- package/esm/menu/menu-core.js +5 -6
- package/esm/overlay/overlay-constants.d.ts +1 -1
- package/esm/overlay/overlay-constants.js +1 -1
- package/esm/overlay/overlay.d.ts +2 -2
- package/esm/overlay/overlay.js +2 -2
- package/esm/select/core/base-select-adapter.js +0 -1
- package/esm/select/core/base-select-core.js +70 -74
- package/esm/select/core/select-utils.d.ts +1 -1
- package/esm/select/core/select-utils.js +2 -2
- package/esm/select/select-dropdown/select-dropdown-adapter.js +1 -3
- package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
- package/esm/table/table-utils.js +10 -12
- package/esm/tabs/tab-bar/tab-bar-core.js +2 -1
- package/esm/text-field/text-field-adapter.js +1 -3
- package/esm/time-picker/time-picker-core.js +5 -5
- package/esm/toast/toast-adapter.js +1 -1
- package/esm/toast/toast-core.js +1 -1
- package/esm/toast/toast.js +2 -1
- package/esm/tooltip/tooltip.js +1 -1
- package/esm/view-switcher/view-switcher-core.js +2 -1
- package/package.json +1 -1
- package/sass/core/styles/tokens/badge/_tokens.scss +1 -1
- package/sass/list/list/list.scss +4 -2
- package/sass/list/list-item/list-item.scss +3 -1
- package/sass/table/forge-table.scss +0 -1
- package/sass/utils/_mixins.scss +7 -8
|
@@ -4,92 +4,251 @@
|
|
|
4
4
|
* License: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { isValidDate } from '@tylertech/forge-core';
|
|
7
|
-
export const ISO_8601_REGEX = /^([
|
|
7
|
+
export const ISO_8601_REGEX = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
|
|
8
8
|
export const ISO_TIMEZONE_REGEX = /a-z/i;
|
|
9
9
|
const FUTURE_YEAR_COERCION = 10; // The number of years in the future to coerce two-digit years into current century
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
const MONTH_ABBREVIATIONS = {
|
|
11
|
+
JAN: 1,
|
|
12
|
+
FEB: 2,
|
|
13
|
+
MAR: 3,
|
|
14
|
+
APR: 4,
|
|
15
|
+
MAY: 5,
|
|
16
|
+
JUN: 6,
|
|
17
|
+
JUL: 7,
|
|
18
|
+
AUG: 8,
|
|
19
|
+
SEP: 9,
|
|
20
|
+
OCT: 10,
|
|
21
|
+
NOV: 11,
|
|
22
|
+
DEC: 12
|
|
23
|
+
};
|
|
24
|
+
const MONTH_NAMES = {
|
|
25
|
+
1: 'JAN',
|
|
26
|
+
2: 'FEB',
|
|
27
|
+
3: 'MAR',
|
|
28
|
+
4: 'APR',
|
|
29
|
+
5: 'MAY',
|
|
30
|
+
6: 'JUN',
|
|
31
|
+
7: 'JUL',
|
|
32
|
+
8: 'AUG',
|
|
33
|
+
9: 'SEP',
|
|
34
|
+
10: 'OCT',
|
|
35
|
+
11: 'NOV',
|
|
36
|
+
12: 'DEC'
|
|
37
|
+
};
|
|
38
|
+
const DATE_PATTERNS = [
|
|
39
|
+
// YYYY-MM-DD (ISO-like numeric)
|
|
40
|
+
{
|
|
41
|
+
regex: /^(\d{4})-(\d{1,2})-(\d{1,2})$/,
|
|
42
|
+
parser: ([year, month, day]) => parseNumericDate(year, month, day, 'YMD')
|
|
43
|
+
},
|
|
44
|
+
// YYYY-MMM-DD
|
|
45
|
+
{
|
|
46
|
+
regex: /^(\d{4})-([A-Za-z]{3})-(\d{1,2})$/,
|
|
47
|
+
parser: ([year, monthAbbr, day]) => parseWithMonthAbbr(year, monthAbbr, day, 'YMD')
|
|
48
|
+
},
|
|
49
|
+
// MM/DD/YYYY or MM/DD/YY
|
|
50
|
+
{
|
|
51
|
+
regex: /^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/,
|
|
52
|
+
parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
|
|
53
|
+
},
|
|
54
|
+
// MM-DD-YYYY or MM-DD-YY
|
|
55
|
+
{
|
|
56
|
+
regex: /^(\d{1,2})-(\d{1,2})-(\d{2,4})$/,
|
|
57
|
+
parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
|
|
58
|
+
},
|
|
59
|
+
// DD/MMM/YYYY
|
|
60
|
+
{
|
|
61
|
+
regex: /^(\d{1,2})\/([A-Za-z]{3})\/(\d{2,4})$/,
|
|
62
|
+
parser: ([day, monthAbbr, year]) => parseWithMonthAbbr(day, monthAbbr, year, 'DMY')
|
|
63
|
+
},
|
|
64
|
+
// DD-MMM-YYYY
|
|
65
|
+
{
|
|
66
|
+
regex: /^(\d{1,2})-([A-Za-z]{3})-(\d{2,4})$/,
|
|
67
|
+
parser: ([day, monthAbbr, year]) => parseWithMonthAbbr(day, monthAbbr, year, 'DMY')
|
|
68
|
+
},
|
|
69
|
+
// Numeric without separators (MMDDYYYY or MMDDYY)
|
|
70
|
+
{
|
|
71
|
+
regex: /^(\d{2})(\d{2})(\d{2,4})$/,
|
|
72
|
+
parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
|
|
73
|
+
},
|
|
74
|
+
// DD.MM.YYYY or DD.MM.YY
|
|
75
|
+
{
|
|
76
|
+
regex: /^(\d{1,2})\.(\d{1,2})\.(\d{2,4})$/,
|
|
77
|
+
parser: ([day, month, year]) => parseNumericDate(day, month, year, 'DMY')
|
|
26
78
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
79
|
+
];
|
|
80
|
+
const FORMAT_CONFIGS = {
|
|
81
|
+
'MM/DD/YYYY': {
|
|
82
|
+
pattern: 'MM/DD/YYYY',
|
|
83
|
+
formatter: date => `${pad(date.getMonth() + 1)}/${pad(date.getDate())}/${date.getFullYear()}`
|
|
84
|
+
},
|
|
85
|
+
'MM/DD/YY': {
|
|
86
|
+
pattern: 'MM/DD/YY',
|
|
87
|
+
formatter: date => `${pad(date.getMonth() + 1)}/${pad(date.getDate())}/${String(date.getFullYear()).slice(-2)}`
|
|
88
|
+
},
|
|
89
|
+
'DD/MMM/YYYY': {
|
|
90
|
+
pattern: 'DD/MMM/YYYY',
|
|
91
|
+
formatter: date => `${pad(date.getDate())}/${MONTH_NAMES[(date.getMonth() + 1)]}/${date.getFullYear()}`
|
|
92
|
+
},
|
|
93
|
+
'MM-DD-YYYY': {
|
|
94
|
+
pattern: 'MM-DD-YYYY',
|
|
95
|
+
formatter: date => `${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${date.getFullYear()}`
|
|
96
|
+
},
|
|
97
|
+
'MM-DD-YY': {
|
|
98
|
+
pattern: 'MM-DD-YY',
|
|
99
|
+
formatter: date => `${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${String(date.getFullYear()).slice(-2)}`
|
|
100
|
+
},
|
|
101
|
+
'DD-MMM-YYYY': {
|
|
102
|
+
pattern: 'DD-MMM-YYYY',
|
|
103
|
+
formatter: date => `${pad(date.getDate())}-${MONTH_NAMES[(date.getMonth() + 1)]}-${date.getFullYear()}`
|
|
104
|
+
},
|
|
105
|
+
'YYYY-MM-DD': {
|
|
106
|
+
pattern: 'YYYY-MM-DD',
|
|
107
|
+
formatter: date => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
|
|
108
|
+
},
|
|
109
|
+
'YYYY-MMM-DD': {
|
|
110
|
+
pattern: 'YYYY-MMM-DD',
|
|
111
|
+
formatter: date => `${date.getFullYear()}-${MONTH_NAMES[(date.getMonth() + 1)]}-${pad(date.getDate())}`
|
|
112
|
+
},
|
|
113
|
+
'DD.MM.YYYY': {
|
|
114
|
+
pattern: 'DD.MM.YYYY',
|
|
115
|
+
formatter: date => `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${date.getFullYear()}`
|
|
116
|
+
},
|
|
117
|
+
'DD.MM.YY': {
|
|
118
|
+
pattern: 'DD.MM.YY',
|
|
119
|
+
formatter: date => `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${String(date.getFullYear()).slice(-2)}`
|
|
31
120
|
}
|
|
32
|
-
|
|
33
|
-
|
|
121
|
+
};
|
|
122
|
+
function pad(num) {
|
|
123
|
+
return String(num).padStart(2, '0');
|
|
124
|
+
}
|
|
125
|
+
function normalizeYear(year) {
|
|
126
|
+
if (year.length === 3) {
|
|
127
|
+
year = year.padStart(4, '0');
|
|
34
128
|
}
|
|
35
|
-
|
|
36
|
-
|
|
129
|
+
if (year.length === 2) {
|
|
130
|
+
const currentYear = new Date().getFullYear();
|
|
131
|
+
const minYear = currentYear - (100 - FUTURE_YEAR_COERCION);
|
|
132
|
+
const maxYear = currentYear + FUTURE_YEAR_COERCION;
|
|
133
|
+
const minCentury = String(minYear).slice(0, 2);
|
|
134
|
+
const maxCentury = String(maxYear).slice(0, 2);
|
|
135
|
+
const maxYearLastTwo = +String(maxYear).slice(2);
|
|
136
|
+
return +year <= maxYearLastTwo ? +`${maxCentury}${year}` : +`${minCentury}${year}`;
|
|
37
137
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
138
|
+
return +year;
|
|
139
|
+
}
|
|
140
|
+
function validateAndClampDate(month, day, year) {
|
|
141
|
+
const clampedMonth = Math.min(Math.max(month, 1), 12);
|
|
142
|
+
const maxDaysInMonth = new Date(year, clampedMonth, 0).getDate();
|
|
143
|
+
const clampedDay = Math.min(Math.max(day, 1), maxDaysInMonth);
|
|
144
|
+
return { month: clampedMonth, day: clampedDay, year };
|
|
145
|
+
}
|
|
146
|
+
function parseMonthAbbreviation(abbr) {
|
|
147
|
+
const upperAbbr = abbr.toUpperCase();
|
|
148
|
+
return MONTH_ABBREVIATIONS[upperAbbr] || null;
|
|
149
|
+
}
|
|
150
|
+
function parseNumericDate(part1, part2, part3, order) {
|
|
151
|
+
let monthStr;
|
|
152
|
+
let dayStr;
|
|
153
|
+
let yearStr;
|
|
154
|
+
if (order === 'MDY') {
|
|
155
|
+
[monthStr, dayStr, yearStr] = [part1, part2, part3];
|
|
43
156
|
}
|
|
44
|
-
if (
|
|
45
|
-
|
|
157
|
+
else if (order === 'YMD') {
|
|
158
|
+
[yearStr, monthStr, dayStr] = [part1, part2, part3];
|
|
46
159
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
160
|
+
else {
|
|
161
|
+
// DMY
|
|
162
|
+
[dayStr, monthStr, yearStr] = [part1, part2, part3];
|
|
50
163
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
164
|
+
// Handle edge cases for incomplete input
|
|
165
|
+
if (monthStr === '0') {
|
|
166
|
+
monthStr = '1';
|
|
167
|
+
}
|
|
168
|
+
if (dayStr === '0') {
|
|
169
|
+
dayStr = '1';
|
|
170
|
+
}
|
|
171
|
+
const year = normalizeYear(yearStr);
|
|
172
|
+
const month = +monthStr;
|
|
173
|
+
const day = +dayStr;
|
|
174
|
+
const { month: validMonth, day: validDay, year: validYear } = validateAndClampDate(month, day, year);
|
|
175
|
+
const date = new Date(validYear, validMonth - 1, validDay, 0, 0, 0, 0);
|
|
176
|
+
return isValidDate(date) ? date : null;
|
|
177
|
+
}
|
|
178
|
+
function parseWithMonthAbbr(part1, monthAbbr, part3, order) {
|
|
179
|
+
const monthNum = parseMonthAbbreviation(monthAbbr);
|
|
180
|
+
if (!monthNum) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
let dayStr;
|
|
184
|
+
let yearStr;
|
|
185
|
+
if (order === 'DMY') {
|
|
186
|
+
[dayStr, yearStr] = [part1, part3];
|
|
58
187
|
}
|
|
59
188
|
else {
|
|
189
|
+
[yearStr, dayStr] = [part1, part3];
|
|
190
|
+
}
|
|
191
|
+
const year = normalizeYear(yearStr);
|
|
192
|
+
const day = +dayStr;
|
|
193
|
+
const { day: validDay, year: validYear } = validateAndClampDate(monthNum, day, year);
|
|
194
|
+
const date = new Date(validYear, monthNum - 1, validDay, 0, 0, 0, 0);
|
|
195
|
+
return isValidDate(date) ? date : null;
|
|
196
|
+
}
|
|
197
|
+
function parseISO8601(value) {
|
|
198
|
+
if (!ISO_8601_REGEX.test(value)) {
|
|
60
199
|
return null;
|
|
61
200
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const normalizedMaxYear = +String(maxYear).slice(2);
|
|
69
|
-
year = +year <= normalizedMaxYear ? `${maxYearCentury}${year}` : `${minYearCentury}${year}`;
|
|
70
|
-
}
|
|
71
|
-
let numMonth = +month;
|
|
72
|
-
let numDay = +day;
|
|
73
|
-
const numYear = +year;
|
|
74
|
-
if (numMonth > 12) {
|
|
75
|
-
numMonth = 12;
|
|
76
|
-
}
|
|
77
|
-
const maxDaysInMonth = new Date(numYear, numMonth, 0).getDate();
|
|
78
|
-
if (numDay > maxDaysInMonth) {
|
|
79
|
-
numDay = maxDaysInMonth;
|
|
80
|
-
}
|
|
81
|
-
const parsedDate = new Date(numYear, numMonth - 1, numDay, 0, 0, 0, 0);
|
|
82
|
-
return isValidDate(parsedDate) ? parsedDate : null;
|
|
201
|
+
const date = new Date(value);
|
|
202
|
+
// Handle timezone offset for ISO strings without explicit timezone
|
|
203
|
+
if (!ISO_TIMEZONE_REGEX.test(value)) {
|
|
204
|
+
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
|
205
|
+
}
|
|
206
|
+
return isValidDate(date) ? date : null;
|
|
83
207
|
}
|
|
84
208
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
209
|
+
* Parses a date string value to a `Date` object in local time.
|
|
210
|
+
* Supports multiple formats as defined in SupportedDateFormats.
|
|
211
|
+
*
|
|
212
|
+
* @param value The date string value to parse
|
|
213
|
+
* @param format Optional format hint for better parsing accuracy
|
|
214
|
+
* @returns Parsed Date object or null if parsing fails
|
|
87
215
|
*/
|
|
88
|
-
export function
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
216
|
+
export function parseDateString(value, format) {
|
|
217
|
+
const cleanValue = value.replace(/[_\s]/g, '');
|
|
218
|
+
// Try ISO 8601 first
|
|
219
|
+
const isoDate = parseISO8601(cleanValue);
|
|
220
|
+
if (isoDate) {
|
|
221
|
+
return isoDate;
|
|
222
|
+
}
|
|
223
|
+
// Try each pattern until one matches
|
|
224
|
+
for (const pattern of DATE_PATTERNS) {
|
|
225
|
+
const match = cleanValue.match(pattern.regex);
|
|
226
|
+
if (match) {
|
|
227
|
+
const result = pattern.parser(match.slice(1));
|
|
228
|
+
if (result) {
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Formats a Date object to a specified string format.
|
|
237
|
+
*
|
|
238
|
+
* @param date The Date object to format
|
|
239
|
+
* @param format The desired output format (defaults to 'MM/DD/YYYY')
|
|
240
|
+
* @returns Formatted date string
|
|
241
|
+
* @throws Error if date is invalid or format is unsupported
|
|
242
|
+
*/
|
|
243
|
+
export function formatDate(date, format = 'MM/DD/YYYY') {
|
|
244
|
+
if (!isValidDate(date)) {
|
|
245
|
+
throw new Error('Invalid date provided');
|
|
246
|
+
}
|
|
247
|
+
const config = FORMAT_CONFIGS[format];
|
|
248
|
+
if (!config) {
|
|
249
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
250
|
+
}
|
|
251
|
+
return config.formatter(date);
|
|
93
252
|
}
|
|
94
253
|
/**
|
|
95
254
|
* Determines if two date objects are equal.
|
|
@@ -18,7 +18,6 @@ export class DismissibleStack {
|
|
|
18
18
|
get dismissing() {
|
|
19
19
|
return this._deferredDismiss?.promise ?? Promise.resolve();
|
|
20
20
|
}
|
|
21
|
-
// eslint-disable-next-line @tylertech-eslint/require-private-modifier
|
|
22
21
|
constructor() {
|
|
23
22
|
/**
|
|
24
23
|
* A set of all elements that are currently eligible for dismissal.
|
|
@@ -9,7 +9,7 @@ import { Platform } from '@tylertech/forge-core';
|
|
|
9
9
|
* @returns {boolean}
|
|
10
10
|
*/
|
|
11
11
|
export function supportsPopover() {
|
|
12
|
-
return
|
|
12
|
+
return Object.prototype.hasOwnProperty.call(HTMLElement.prototype, 'popover');
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Detects if the browser supports ARIA properties in Element Internals.
|
|
@@ -19,7 +19,7 @@ export function supportsPopover() {
|
|
|
19
19
|
* @returns {boolean}
|
|
20
20
|
*/
|
|
21
21
|
export function supportsElementInternalsAria() {
|
|
22
|
-
return
|
|
22
|
+
return Object.prototype.hasOwnProperty.call(ElementInternals.prototype, 'role');
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Detects if the browser supports the hovering elements as the users primary input mechanism.
|
|
@@ -7,6 +7,7 @@ import { DateRange, DayOfWeek, ICalendarComponent } from '../../calendar';
|
|
|
7
7
|
import { ICalendarDropdown, ICalendarDropdownPopupConfig } from '../../calendar/calendar-dropdown';
|
|
8
8
|
import { BaseAdapter, IBaseAdapter, IDateInputMaskOptions } from '../../core';
|
|
9
9
|
import { BaseComponent } from '../../core/base/base-component';
|
|
10
|
+
import { IIconButtonComponent } from '../../icon-button';
|
|
10
11
|
import { IDatePickerCalendarDropdownText } from './base-date-picker-constants';
|
|
11
12
|
export interface IBaseDatePickerAdapter extends IBaseAdapter {
|
|
12
13
|
initialize(): void;
|
|
@@ -98,6 +99,6 @@ export declare abstract class BaseDatePickerAdapter<T extends BaseComponent> ext
|
|
|
98
99
|
setCalendarText(text: IDatePickerCalendarDropdownText): void;
|
|
99
100
|
propagateCalendarKey(evt: KeyboardEvent): void;
|
|
100
101
|
tryCreateToggle(): void;
|
|
101
|
-
protected _createToggleElement():
|
|
102
|
+
protected _createToggleElement(): IIconButtonComponent;
|
|
102
103
|
protected _getDefaultTargetElement(): HTMLElement;
|
|
103
104
|
}
|
|
@@ -173,6 +173,10 @@ export class BaseDatePickerAdapter extends BaseAdapter {
|
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
175
|
const iconButtonElement = this._createToggleElement();
|
|
176
|
+
// Inherit the density from the text field in certain cases
|
|
177
|
+
if (textField.density === 'extra-small') {
|
|
178
|
+
iconButtonElement.density = 'small';
|
|
179
|
+
}
|
|
176
180
|
textField.appendChild(iconButtonElement);
|
|
177
181
|
this._toggleElement = iconButtonElement;
|
|
178
182
|
}
|
|
@@ -5,10 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Masked, InputMask, type AppendFlags, type FactoryArg } from 'imask';
|
|
7
7
|
import { DayOfWeek, ICalendarDateSelectEventData } from '../../calendar';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export
|
|
11
|
-
export
|
|
8
|
+
import { type IDatePickerComponent } from '../date-picker';
|
|
9
|
+
import { SupportedDateFormats } from '../../core/utils/date-utils';
|
|
10
|
+
export type DatePickerParseCallback = (value: string) => Date | null;
|
|
11
|
+
export type DatePickerFormatCallback = (value: Date | null) => string | null;
|
|
12
|
+
export type DatePickerPrepareMaskCallback = (value: string, masked: Masked<string>, flags: AppendFlags, maskInstance: InputMask<FactoryArg>) => string;
|
|
13
|
+
export type DatePickerValueMode = 'object' | 'string' | 'iso-string';
|
|
14
|
+
export type DatePickerShortcuts = IDatePickerShortcuts | 'off' | undefined;
|
|
15
|
+
export type DatePickerDateFormat = SupportedDateFormats;
|
|
16
|
+
export interface IDatePickerShortcuts {
|
|
17
|
+
[key: string]: (context: {
|
|
18
|
+
instance: IDatePickerComponent;
|
|
19
|
+
}) => Date | null | undefined | void;
|
|
20
|
+
}
|
|
12
21
|
export interface IDatePickerCalendarDropdownConfig<T> {
|
|
13
22
|
value?: T | null;
|
|
14
23
|
min?: Date | null;
|
|
@@ -45,7 +54,9 @@ export declare const BASE_DATE_PICKER_CONSTANTS: {
|
|
|
45
54
|
MASKED: string;
|
|
46
55
|
MASK_FORMAT: string;
|
|
47
56
|
SHOW_MASK_FORMAT: string;
|
|
57
|
+
DATE_FORMAT: string;
|
|
48
58
|
VALUE_MODE: string;
|
|
59
|
+
SHORTCUTS: string;
|
|
49
60
|
ALLOW_INVALID_DATE: string;
|
|
50
61
|
SHOW_TODAY: string;
|
|
51
62
|
SHOW_CLEAR: string;
|
|
@@ -61,4 +72,8 @@ export declare const BASE_DATE_PICKER_CONSTANTS: {
|
|
|
61
72
|
INPUT: string;
|
|
62
73
|
TOGGLE: string;
|
|
63
74
|
};
|
|
75
|
+
defaults: {
|
|
76
|
+
DATE_FORMAT: DatePickerDateFormat;
|
|
77
|
+
};
|
|
78
|
+
supportedDateFormats: SupportedDateFormats[];
|
|
64
79
|
};
|
|
@@ -12,7 +12,9 @@ const observedAttributes = {
|
|
|
12
12
|
MASKED: 'masked',
|
|
13
13
|
MASK_FORMAT: 'mask-format',
|
|
14
14
|
SHOW_MASK_FORMAT: 'show-mask-format',
|
|
15
|
+
DATE_FORMAT: 'date-format',
|
|
15
16
|
VALUE_MODE: 'value-mode',
|
|
17
|
+
SHORTCUTS: 'shortcuts',
|
|
16
18
|
ALLOW_INVALID_DATE: 'allow-invalid-date',
|
|
17
19
|
SHOW_TODAY: 'show-today',
|
|
18
20
|
SHOW_CLEAR: 'show-clear',
|
|
@@ -28,8 +30,25 @@ const selectors = {
|
|
|
28
30
|
INPUT: 'input',
|
|
29
31
|
TOGGLE: '[forge-date-picker-toggle],[data-forge-date-picker-toggle]'
|
|
30
32
|
};
|
|
33
|
+
const defaults = {
|
|
34
|
+
DATE_FORMAT: 'MM/DD/YYYY'
|
|
35
|
+
};
|
|
36
|
+
const supportedDateFormats = [
|
|
37
|
+
'MM/DD/YYYY',
|
|
38
|
+
'MM/DD/YY',
|
|
39
|
+
'DD/MMM/YYYY',
|
|
40
|
+
'MM-DD-YYYY',
|
|
41
|
+
'MM-DD-YY',
|
|
42
|
+
'DD-MMM-YYYY',
|
|
43
|
+
'YYYY-MM-DD',
|
|
44
|
+
'YYYY-MMM-DD',
|
|
45
|
+
'DD.MM.YYYY',
|
|
46
|
+
'DD.MM.YY'
|
|
47
|
+
];
|
|
31
48
|
export const BASE_DATE_PICKER_CONSTANTS = {
|
|
32
49
|
observedAttributes,
|
|
33
50
|
attributes,
|
|
34
|
-
selectors
|
|
51
|
+
selectors,
|
|
52
|
+
defaults,
|
|
53
|
+
supportedDateFormats
|
|
35
54
|
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { CalendarMode, DayOfWeek, ICalendarDateSelectEventData } from '../../calendar/calendar-constants';
|
|
7
7
|
import { IBaseDatePickerAdapter } from './base-date-picker-adapter';
|
|
8
|
-
import { DatePickerFormatCallback, DatePickerParseCallback, DatePickerPrepareMaskCallback, DatePickerValueMode, IDatePickerCalendarDropdownText } from './base-date-picker-constants';
|
|
8
|
+
import { DatePickerFormatCallback, DatePickerParseCallback, DatePickerPrepareMaskCallback, IDatePickerShortcuts, DatePickerValueMode, IDatePickerCalendarDropdownText, DatePickerShortcuts, DatePickerDateFormat } from './base-date-picker-constants';
|
|
9
9
|
export interface IBaseDatePickerCore<TValue> {
|
|
10
10
|
value: TValue | null | undefined;
|
|
11
11
|
min: Date | string | null | undefined;
|
|
@@ -20,6 +20,7 @@ export interface IBaseDatePickerCore<TValue> {
|
|
|
20
20
|
masked: boolean;
|
|
21
21
|
maskFormat: string;
|
|
22
22
|
showMaskFormat: boolean;
|
|
23
|
+
dateFormat: DatePickerDateFormat;
|
|
23
24
|
valueMode: DatePickerValueMode;
|
|
24
25
|
notifyInputValueChanges: boolean;
|
|
25
26
|
allowInvalidDate: boolean;
|
|
@@ -45,7 +46,9 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
|
|
|
45
46
|
protected _masked: boolean;
|
|
46
47
|
protected _maskFormat: string;
|
|
47
48
|
protected _showMaskFormat: boolean;
|
|
49
|
+
protected _dateFormat: DatePickerDateFormat;
|
|
48
50
|
protected _valueMode: DatePickerValueMode;
|
|
51
|
+
protected _shortcuts: IDatePickerShortcuts | undefined;
|
|
49
52
|
protected _notifyInputValueChanges: boolean;
|
|
50
53
|
protected _allowInvalidDate: boolean;
|
|
51
54
|
protected _showToday: boolean;
|
|
@@ -95,6 +98,7 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
|
|
|
95
98
|
protected _onInputBlur(evt: FocusEvent): void;
|
|
96
99
|
protected _openCalendar(emitOpenEvent?: boolean): void;
|
|
97
100
|
protected _closeCalendar(emitCloseEvent?: boolean): void;
|
|
101
|
+
private _getDefaultShortcuts;
|
|
98
102
|
protected _onInputKeydown(evt: KeyboardEvent): void;
|
|
99
103
|
protected _getSanitizedDateString(value: string): string;
|
|
100
104
|
private _onToggleMousedown;
|
|
@@ -102,19 +106,21 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
|
|
|
102
106
|
private _onMonthChanged;
|
|
103
107
|
private _onActiveDescendantChanged;
|
|
104
108
|
protected _formatInputValue(): void;
|
|
105
|
-
protected _formatDate(date: Date | null | undefined): string;
|
|
109
|
+
protected _formatDate(date: Date | null | undefined): string | null;
|
|
106
110
|
protected _parseDateString(value: string): Date | null;
|
|
107
111
|
protected _coerceDateValue(value?: Date | string | null): Date | null | undefined;
|
|
108
112
|
protected _getTypedValue(value: Date | null | undefined): Date | string | null | undefined;
|
|
109
113
|
protected _isDateValueAcceptable(value?: Date | null): boolean;
|
|
110
114
|
protected _initializeMask(): void;
|
|
111
|
-
|
|
115
|
+
protected _applyMask(): void;
|
|
112
116
|
protected _applyMin(): void;
|
|
113
117
|
protected _applyMax(): void;
|
|
114
118
|
private _applyDisableDayCallback;
|
|
115
119
|
private _applyDisabled;
|
|
116
120
|
get valueMode(): DatePickerValueMode;
|
|
117
121
|
set valueMode(value: DatePickerValueMode);
|
|
122
|
+
get shortcuts(): DatePickerShortcuts;
|
|
123
|
+
set shortcuts(value: DatePickerShortcuts);
|
|
118
124
|
get min(): Date | string | null | undefined;
|
|
119
125
|
set min(value: Date | string | null | undefined);
|
|
120
126
|
get max(): Date | string | null | undefined;
|
|
@@ -133,6 +139,8 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
|
|
|
133
139
|
set maskFormat(value: string);
|
|
134
140
|
get showMaskFormat(): boolean;
|
|
135
141
|
set showMaskFormat(value: boolean);
|
|
142
|
+
get dateFormat(): DatePickerDateFormat;
|
|
143
|
+
set dateFormat(value: DatePickerDateFormat);
|
|
136
144
|
get notifyInputValueChanges(): boolean;
|
|
137
145
|
set notifyInputValueChanges(value: boolean);
|
|
138
146
|
get allowInvalidDate(): boolean;
|