@aurodesignsystem/auro-formkit 3.1.0-beta.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -3
- package/components/checkbox/demo/api.min.js +468 -25
- package/components/checkbox/demo/index.min.js +468 -25
- package/components/checkbox/dist/index.js +468 -25
- package/components/checkbox/dist/registered.js +468 -25
- package/components/combobox/demo/api.md +1 -1
- package/components/combobox/demo/api.min.js +1265 -235
- package/components/combobox/demo/index.min.js +1265 -235
- package/components/combobox/dist/auro-combobox.d.ts +32 -5
- package/components/combobox/dist/index.js +1130 -100
- package/components/combobox/dist/registered.js +1130 -100
- package/components/counter/demo/api.md +1 -1
- package/components/counter/demo/api.min.js +575 -71
- package/components/counter/demo/index.min.js +575 -71
- package/components/counter/dist/auro-counter-group.d.ts +2 -5
- package/components/counter/dist/index.js +575 -71
- package/components/counter/dist/registered.js +575 -71
- package/components/datepicker/demo/api.md +0 -1
- package/components/datepicker/demo/api.min.js +1077 -106
- package/components/datepicker/demo/index.min.js +1077 -106
- package/components/datepicker/dist/auro-datepicker.d.ts +0 -13
- package/components/datepicker/dist/index.js +1077 -106
- package/components/datepicker/dist/registered.js +1077 -106
- package/components/dropdown/demo/api.md +9 -6
- package/components/dropdown/demo/api.min.js +107 -43
- package/components/dropdown/demo/index.md +0 -83
- package/components/dropdown/demo/index.min.js +107 -43
- package/components/dropdown/dist/auro-dropdown.d.ts +30 -12
- package/components/dropdown/dist/index.js +107 -43
- package/components/dropdown/dist/registered.js +107 -43
- package/components/input/demo/api.md +4 -1
- package/components/input/demo/api.min.js +503 -25
- package/components/input/demo/index.min.js +503 -25
- package/components/input/dist/base-input.d.ts +24 -0
- package/components/input/dist/index.js +503 -25
- package/components/input/dist/registered.js +503 -25
- package/components/radio/demo/api.min.js +468 -25
- package/components/radio/demo/index.min.js +468 -25
- package/components/radio/dist/index.js +468 -25
- package/components/radio/dist/registered.js +468 -25
- package/components/select/demo/api.md +1 -1
- package/components/select/demo/api.min.js +575 -71
- package/components/select/demo/index.md +1 -46
- package/components/select/demo/index.min.js +575 -71
- package/components/select/dist/auro-select.d.ts +2 -5
- package/components/select/dist/index.js +575 -71
- package/components/select/dist/registered.js +575 -71
- package/package.json +2 -2
- package/components/form/demo/autocomplete.html +0 -15
|
@@ -114,11 +114,420 @@ let AuroLibraryRuntimeUtils$4 = class AuroLibraryRuntimeUtils {
|
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
+
let DateFormatter$1 = class DateFormatter {
|
|
118
|
+
|
|
119
|
+
constructor() {
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @description Parses a date string into its components.
|
|
123
|
+
* @param {string} dateStr - Date string to parse.
|
|
124
|
+
* @param {string} format - Date format to parse.
|
|
125
|
+
* @returns {Object<key["month" | "day" | "year"]: number>|undefined}
|
|
126
|
+
*/
|
|
127
|
+
this.parseDate = (dateStr, format = 'mm/dd/yyyy') => {
|
|
128
|
+
|
|
129
|
+
// Guard Clause: Date string is defined
|
|
130
|
+
if (!dateStr) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Assume the separator is a "/" a defined in our code base
|
|
135
|
+
const separator = '/';
|
|
136
|
+
|
|
137
|
+
// Get the parts of the date and format
|
|
138
|
+
const valueParts = dateStr.split(separator);
|
|
139
|
+
const formatParts = format.split(separator);
|
|
140
|
+
|
|
141
|
+
// Check if the value and format have the correct number of parts
|
|
142
|
+
if (valueParts.length !== formatParts.length) {
|
|
143
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Date string and format length do not match');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Holds the result to be returned
|
|
147
|
+
const result = formatParts.reduce((acc, part, index) => {
|
|
148
|
+
const value = valueParts[index];
|
|
149
|
+
|
|
150
|
+
if ((/m/iu).test(part)) {
|
|
151
|
+
acc.month = value;
|
|
152
|
+
} else if ((/d/iu).test(part)) {
|
|
153
|
+
acc.day = value;
|
|
154
|
+
} else if ((/y/iu).test(part)) {
|
|
155
|
+
acc.year = value;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return acc;
|
|
159
|
+
}, {});
|
|
160
|
+
|
|
161
|
+
// If we found all the parts, return the result
|
|
162
|
+
if (result.month && result.year) {
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Throw an error to let the dev know we were unable to parse the date string
|
|
167
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Unable to parse date string');
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Convert a date object to string format.
|
|
172
|
+
* @param {Object} date - Date to convert to string.
|
|
173
|
+
* @returns {Object} Returns the date as a string.
|
|
174
|
+
*/
|
|
175
|
+
this.getDateAsString = (date) => date.toLocaleDateString(undefined, {
|
|
176
|
+
year: "numeric",
|
|
177
|
+
month: "2-digit",
|
|
178
|
+
day: "2-digit",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Converts a date string to a North American date format.
|
|
183
|
+
* @param {String} dateStr - Date to validate.
|
|
184
|
+
* @param {String} format - Date format to validate against.
|
|
185
|
+
* @returns {Boolean}
|
|
186
|
+
*/
|
|
187
|
+
this.toNorthAmericanFormat = (dateStr, format) => {
|
|
188
|
+
|
|
189
|
+
if (format === 'mm/dd/yyyy') {
|
|
190
|
+
return dateStr;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const parsedDate = this.parseDate(dateStr, format);
|
|
194
|
+
|
|
195
|
+
if (!parsedDate) {
|
|
196
|
+
throw new Error('AuroDatepickerUtilities | toNorthAmericanFormat: Unable to parse date string');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const { month, day, year } = parsedDate;
|
|
200
|
+
|
|
201
|
+
const dateParts = [];
|
|
202
|
+
if (month) {
|
|
203
|
+
dateParts.push(month);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (day) {
|
|
207
|
+
dateParts.push(day);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (year) {
|
|
211
|
+
dateParts.push(year);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return dateParts.join('/');
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const dateFormatter$1 = new DateFormatter$1();
|
|
219
|
+
|
|
220
|
+
// filepath: dateConstraints.mjs
|
|
221
|
+
const DATE_UTIL_CONSTRAINTS$1 = {
|
|
222
|
+
maxDay: 31,
|
|
223
|
+
maxMonth: 12,
|
|
224
|
+
maxYear: 2400,
|
|
225
|
+
minDay: 1,
|
|
226
|
+
minMonth: 1,
|
|
227
|
+
minYear: 1900,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
let AuroDateUtilitiesBase$1 = class AuroDateUtilitiesBase {
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @description The maximum day value allowed by the various utilities in this class.
|
|
234
|
+
* @readonly
|
|
235
|
+
* @type {Number}
|
|
236
|
+
*/
|
|
237
|
+
get maxDay() {
|
|
238
|
+
return DATE_UTIL_CONSTRAINTS$1.maxDay;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @description The maximum month value allowed by the various utilities in this class.
|
|
243
|
+
* @readonly
|
|
244
|
+
* @type {Number}
|
|
245
|
+
*/
|
|
246
|
+
get maxMonth() {
|
|
247
|
+
return DATE_UTIL_CONSTRAINTS$1.maxMonth;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @description The maximum year value allowed by the various utilities in this class.
|
|
252
|
+
* @readonly
|
|
253
|
+
* @type {Number}
|
|
254
|
+
*/
|
|
255
|
+
get maxYear() {
|
|
256
|
+
return DATE_UTIL_CONSTRAINTS$1.maxYear;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @description The minimum day value allowed by the various utilities in this class.
|
|
261
|
+
* @readonly
|
|
262
|
+
* @type {Number}
|
|
263
|
+
*/
|
|
264
|
+
get minDay() {
|
|
265
|
+
return DATE_UTIL_CONSTRAINTS$1.minDay;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @description The minimum month value allowed by the various utilities in this class.
|
|
270
|
+
* @readonly
|
|
271
|
+
* @type {Number}
|
|
272
|
+
*/
|
|
273
|
+
get minMonth() {
|
|
274
|
+
return DATE_UTIL_CONSTRAINTS$1.minMonth;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @description The minimum year value allowed by the various utilities in this class.
|
|
279
|
+
* @readonly
|
|
280
|
+
* @type {Number}
|
|
281
|
+
*/
|
|
282
|
+
get minYear() {
|
|
283
|
+
return DATE_UTIL_CONSTRAINTS$1.minYear;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
/* eslint-disable no-magic-numbers */
|
|
288
|
+
|
|
289
|
+
let AuroDateUtilities$1 = class AuroDateUtilities extends AuroDateUtilitiesBase$1 {
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Returns the current century.
|
|
293
|
+
* @returns {String} The current century.
|
|
294
|
+
*/
|
|
295
|
+
getCentury () {
|
|
296
|
+
return String(new Date().getFullYear()).slice(0, 2);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Returns a four digit year.
|
|
301
|
+
* @param {String} year - The year to convert to four digits.
|
|
302
|
+
* @returns {String} The four digit year.
|
|
303
|
+
*/
|
|
304
|
+
getFourDigitYear (year) {
|
|
305
|
+
|
|
306
|
+
const strYear = String(year).trim();
|
|
307
|
+
return strYear.length <= 2 ? this.getCentury() + strYear : strYear;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
constructor() {
|
|
311
|
+
|
|
312
|
+
super();
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Compares two dates to see if they match.
|
|
316
|
+
* @param {Object} date1 - First date to compare.
|
|
317
|
+
* @param {Object} date2 - Second date to compare.
|
|
318
|
+
* @returns {Boolean} Returns true if the dates match.
|
|
319
|
+
*/
|
|
320
|
+
this.datesMatch = (date1, date2) => new Date(date1).getTime() === new Date(date2).getTime();
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Returns true if value passed in is a valid date.
|
|
324
|
+
* @param {String} date - Date to validate.
|
|
325
|
+
* @param {String} format - Date format to validate against.
|
|
326
|
+
* @returns {Boolean}
|
|
327
|
+
*/
|
|
328
|
+
this.validDateStr = (date, format) => {
|
|
329
|
+
|
|
330
|
+
// The length we expect the date string to be
|
|
331
|
+
const dateStrLength = format.length;
|
|
332
|
+
|
|
333
|
+
// Guard Clause: Date and format are defined
|
|
334
|
+
if (typeof date === "undefined" || typeof format === "undefined") {
|
|
335
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date and format are required');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Guard Clause: Date should be of type string
|
|
339
|
+
if (typeof date !== "string") {
|
|
340
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date must be a string');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Guard Clause: Format should be of type string
|
|
344
|
+
if (typeof format !== "string") {
|
|
345
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Format must be a string');
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Guard Clause: Length is what we expect it to be
|
|
349
|
+
if (date.length !== dateStrLength) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
// Get a formatted date string and parse it
|
|
353
|
+
const dateParts = dateFormatter$1.parseDate(date, format);
|
|
354
|
+
|
|
355
|
+
// Guard Clause: Date parse succeeded
|
|
356
|
+
if (!dateParts) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Create the expected date string based on the date parts
|
|
361
|
+
const expectedDateStr = `${dateParts.month}/${dateParts.day || "01"}/${this.getFourDigitYear(dateParts.year)}`;
|
|
362
|
+
|
|
363
|
+
// Generate a date object that we will extract a string date from to compare to the passed in date string
|
|
364
|
+
const dateObj = new Date(this.getFourDigitYear(dateParts.year), dateParts.month - 1, dateParts.day || 1);
|
|
365
|
+
|
|
366
|
+
// Get the date string of the date object we created from the string date
|
|
367
|
+
const actualDateStr = dateFormatter$1.getDateAsString(dateObj);
|
|
368
|
+
|
|
369
|
+
// Guard Clause: Generated date matches date string input
|
|
370
|
+
if (expectedDateStr !== actualDateStr) {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// If we passed all other checks, we can assume the date is valid
|
|
375
|
+
return true;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Determines if a string date value matches the format provided.
|
|
380
|
+
* @param {string} value = The date string value.
|
|
381
|
+
* @param { string} format = The date format to match against.
|
|
382
|
+
* @returns {boolean}
|
|
383
|
+
*/
|
|
384
|
+
this.dateAndFormatMatch = (value, format) => {
|
|
385
|
+
|
|
386
|
+
// Ensure we have both values we need to do the comparison
|
|
387
|
+
if (!value || !format) {
|
|
388
|
+
throw new Error('AuroFormValidation | dateFormatMatch: value and format are required');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// If the lengths are different, they cannot match
|
|
392
|
+
if (value.length !== format.length) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Get the parts of the date
|
|
397
|
+
const dateParts = dateFormatter$1.parseDate(value, format);
|
|
398
|
+
|
|
399
|
+
// Validator for day
|
|
400
|
+
const dayValueIsValid = (day) => {
|
|
401
|
+
|
|
402
|
+
// Guard clause: if there is no day in the dateParts, we can ignore this check.
|
|
403
|
+
if (!dateParts.day) {
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Guard clause: ensure day exists.
|
|
408
|
+
if (!day) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Convert day to number
|
|
413
|
+
const numDay = Number.parseInt(day, 10);
|
|
414
|
+
|
|
415
|
+
// Guard clause: ensure day is a valid integer
|
|
416
|
+
if (Number.isNaN(numDay)) {
|
|
417
|
+
throw new Error('AuroDatepickerUtilities | dayValueIsValid: Unable to parse day value integer');
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Guard clause: ensure day is within the valid range
|
|
421
|
+
if (numDay < this.minDay || numDay > this.maxDay) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Default return
|
|
426
|
+
return true;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
// Validator for month
|
|
430
|
+
const monthValueIsValid = (month) => {
|
|
431
|
+
|
|
432
|
+
// Guard clause: ensure month exists.
|
|
433
|
+
if (!month) {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Convert month to number
|
|
438
|
+
const numMonth = Number.parseInt(month, 10);
|
|
439
|
+
|
|
440
|
+
// Guard clause: ensure month is a valid integer
|
|
441
|
+
if (Number.isNaN(numMonth)) {
|
|
442
|
+
throw new Error('AuroDatepickerUtilities | monthValueIsValid: Unable to parse month value integer');
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Guard clause: ensure month is within the valid range
|
|
446
|
+
if (numMonth < this.minMonth || numMonth > this.maxMonth) {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Default return
|
|
451
|
+
return true;
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
// Validator for year
|
|
455
|
+
const yearIsValid = (_year) => {
|
|
456
|
+
|
|
457
|
+
// Guard clause: ensure year exists.
|
|
458
|
+
if (!_year) {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Get the full year
|
|
463
|
+
const year = this.getFourDigitYear(_year);
|
|
464
|
+
|
|
465
|
+
// Convert year to number
|
|
466
|
+
const numYear = Number.parseInt(year, 10);
|
|
467
|
+
|
|
468
|
+
// Guard clause: ensure year is a valid integer
|
|
469
|
+
if (Number.isNaN(numYear)) {
|
|
470
|
+
throw new Error('AuroDatepickerUtilities | yearValueIsValid: Unable to parse year value integer');
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Guard clause: ensure year is within the valid range
|
|
474
|
+
if (numYear < this.minYear || numYear > this.maxYear) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Default return
|
|
479
|
+
return true;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// Self-contained checks for month, day, and year
|
|
483
|
+
const checks = [
|
|
484
|
+
monthValueIsValid(dateParts.month),
|
|
485
|
+
dayValueIsValid(dateParts.day),
|
|
486
|
+
yearIsValid(dateParts.year)
|
|
487
|
+
];
|
|
488
|
+
|
|
489
|
+
// If any of the checks failed, the date format does not match and the result is invalid
|
|
490
|
+
const isValid = checks.every((check) => check === true);
|
|
491
|
+
|
|
492
|
+
// If the check is invalid, return false
|
|
493
|
+
if (!isValid) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Default case
|
|
498
|
+
return true;
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// Export a class instance
|
|
504
|
+
const dateUtilities$1 = new AuroDateUtilities$1();
|
|
505
|
+
|
|
506
|
+
// Export the class instance methods individually
|
|
507
|
+
const {
|
|
508
|
+
datesMatch: datesMatch$1,
|
|
509
|
+
validDateStr: validDateStr$1,
|
|
510
|
+
dateAndFormatMatch: dateAndFormatMatch$1,
|
|
511
|
+
minDay: minDay$1,
|
|
512
|
+
minMonth: minMonth$1,
|
|
513
|
+
minYear: minYear$1,
|
|
514
|
+
maxDay: maxDay$1,
|
|
515
|
+
maxMonth: maxMonth$1,
|
|
516
|
+
maxYear: maxYear$1
|
|
517
|
+
} = dateUtilities$1;
|
|
518
|
+
|
|
519
|
+
const {
|
|
520
|
+
toNorthAmericanFormat: toNorthAmericanFormat$1,
|
|
521
|
+
parseDate: parseDate$1,
|
|
522
|
+
getDateAsString: getDateAsString$1
|
|
523
|
+
} = dateFormatter$1;
|
|
524
|
+
|
|
117
525
|
// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
118
526
|
// See LICENSE in the project root for license information.
|
|
119
527
|
|
|
120
528
|
|
|
121
529
|
let AuroFormValidation$1 = class AuroFormValidation {
|
|
530
|
+
|
|
122
531
|
constructor() {
|
|
123
532
|
this.runtimeUtils = new AuroLibraryRuntimeUtils$4();
|
|
124
533
|
}
|
|
@@ -210,17 +619,17 @@ let AuroFormValidation$1 = class AuroFormValidation {
|
|
|
210
619
|
]
|
|
211
620
|
}
|
|
212
621
|
};
|
|
213
|
-
|
|
622
|
+
|
|
214
623
|
let elementType;
|
|
215
624
|
if (this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
216
625
|
elementType = 'input';
|
|
217
626
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-counter') || this.runtimeUtils.elementMatch(elem, 'auro-counter-group')) {
|
|
218
627
|
elementType = 'counter';
|
|
219
628
|
}
|
|
220
|
-
|
|
629
|
+
|
|
221
630
|
if (elementType) {
|
|
222
631
|
const rules = validationRules[elementType];
|
|
223
|
-
|
|
632
|
+
|
|
224
633
|
if (rules) {
|
|
225
634
|
Object.values(rules).flat().forEach(rule => {
|
|
226
635
|
if (rule.check(elem)) {
|
|
@@ -246,48 +655,82 @@ let AuroFormValidation$1 = class AuroFormValidation {
|
|
|
246
655
|
if (!elem.value.match(emailRegex)) {
|
|
247
656
|
elem.validity = 'patternMismatch';
|
|
248
657
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
658
|
+
return;
|
|
249
659
|
}
|
|
250
660
|
} else if (elem.type === 'credit-card') {
|
|
251
661
|
if (elem.value.length > 0 && elem.value.length < elem.validationCCLength) {
|
|
252
662
|
elem.validity = 'tooShort';
|
|
253
663
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
664
|
+
return;
|
|
254
665
|
}
|
|
255
666
|
} else if (elem.type === 'number') {
|
|
256
667
|
if (elem.max !== undefined && Number(elem.max) < Number(elem.value)) {
|
|
257
668
|
elem.validity = 'rangeOverflow';
|
|
258
669
|
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
670
|
+
return;
|
|
259
671
|
}
|
|
260
672
|
|
|
261
673
|
if (elem.min !== undefined && elem.value?.length > 0 && Number(elem.min) > Number(elem.value)) {
|
|
262
674
|
elem.validity = 'rangeUnderflow';
|
|
263
675
|
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
676
|
+
return;
|
|
264
677
|
}
|
|
265
|
-
} else if (elem.type === 'date') {
|
|
266
|
-
|
|
678
|
+
} else if (elem.type === 'date' && elem.value?.length > 0) {
|
|
679
|
+
|
|
680
|
+
// Guard Clause: if the value is too short
|
|
681
|
+
if (elem.value.length < elem.lengthForType) {
|
|
682
|
+
|
|
267
683
|
elem.validity = 'tooShort';
|
|
268
684
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Guard Clause: If the value is too long for the type
|
|
689
|
+
if (elem.value?.length > elem.lengthForType) {
|
|
690
|
+
|
|
691
|
+
elem.validity = 'tooLong';
|
|
692
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Validate that the date passed was the correct format
|
|
697
|
+
if (!dateAndFormatMatch$1(elem.value, elem.format)) {
|
|
698
|
+
elem.validity = 'patternMismatch';
|
|
699
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || 'Invalid Date Format Entered';
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// Validate that the date passed was a valid date
|
|
704
|
+
if (!validDateStr$1(elem.value, elem.format)) {
|
|
705
|
+
elem.validity = 'invalidDate';
|
|
706
|
+
elem.errorMessage = elem.setCustomValidityInvalidDate || elem.setCustomValidity || 'Invalid Date Entered';
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
272
709
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
710
|
+
// Perform the rest of the validation
|
|
711
|
+
const formattedValue = toNorthAmericanFormat$1(elem.value, elem.format);
|
|
712
|
+
const valueDate = new Date(formattedValue);
|
|
276
713
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
714
|
+
// // Validate max date
|
|
715
|
+
if (elem.max?.length === elem.lengthForType) {
|
|
716
|
+
|
|
717
|
+
const maxDate = new Date(toNorthAmericanFormat$1(elem.max, elem.format));
|
|
718
|
+
|
|
719
|
+
if (valueDate > maxDate) {
|
|
720
|
+
elem.validity = 'rangeOverflow';
|
|
721
|
+
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
722
|
+
return;
|
|
281
723
|
}
|
|
724
|
+
}
|
|
282
725
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
726
|
+
// Validate min date
|
|
727
|
+
if (elem.min?.length === elem.lengthForType) {
|
|
728
|
+
const minDate = new Date(toNorthAmericanFormat$1(elem.min, elem.format));
|
|
286
729
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
730
|
+
if (valueDate < minDate) {
|
|
731
|
+
elem.validity = 'rangeUnderflow';
|
|
732
|
+
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
733
|
+
return;
|
|
291
734
|
}
|
|
292
735
|
}
|
|
293
736
|
}
|
|
@@ -406,7 +849,7 @@ let AuroFormValidation$1 = class AuroFormValidation {
|
|
|
406
849
|
if (input.validationMessage.length > 0) {
|
|
407
850
|
elem.errorMessage = input.validationMessage;
|
|
408
851
|
}
|
|
409
|
-
} else if (this.inputElements?.length > 0
|
|
852
|
+
} else if (this.inputElements?.length > 0 && elem.errorMessage === '') {
|
|
410
853
|
const firstInput = this.inputElements[0];
|
|
411
854
|
|
|
412
855
|
if (firstInput.validationMessage.length > 0) {
|
|
@@ -2268,7 +2711,7 @@ class AuroFloatingUI {
|
|
|
2268
2711
|
/**
|
|
2269
2712
|
* @private
|
|
2270
2713
|
* getting called on 'blur' in trigger or `focusin` in document
|
|
2271
|
-
*
|
|
2714
|
+
*
|
|
2272
2715
|
* Hides the bib if focus moves outside of the trigger or bib, unless a 'noHideOnThisFocusLoss' flag is set.
|
|
2273
2716
|
* This method checks if the currently active element is still within the trigger or bib.
|
|
2274
2717
|
* If not, and if the bib isn't in fullscreen mode with focus lost, it hides the bib.
|
|
@@ -2384,7 +2827,7 @@ class AuroFloatingUI {
|
|
|
2384
2827
|
// Close any other dropdown that is already open
|
|
2385
2828
|
const existedVisibleFloatingUI = document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
2386
2829
|
if (existedVisibleFloatingUI && existedVisibleFloatingUI !== this &&
|
|
2387
|
-
existedVisibleFloatingUI.isPopoverVisible &&
|
|
2830
|
+
existedVisibleFloatingUI.element.isPopoverVisible &&
|
|
2388
2831
|
document.expandedAuroFloater.eventPrefix === this.eventPrefix) {
|
|
2389
2832
|
document.expandedAuroFloater.hideBib();
|
|
2390
2833
|
}
|
|
@@ -2560,7 +3003,7 @@ class AuroFloatingUI {
|
|
|
2560
3003
|
this.id = window.crypto.randomUUID();
|
|
2561
3004
|
this.element.setAttribute('id', this.id);
|
|
2562
3005
|
}
|
|
2563
|
-
|
|
3006
|
+
|
|
2564
3007
|
this.element.bib.setAttribute("id", `${this.id}-floater-bib`);
|
|
2565
3008
|
}
|
|
2566
3009
|
|
|
@@ -2613,7 +3056,7 @@ class AuroFloatingUI {
|
|
|
2613
3056
|
if (this.element.bib) {
|
|
2614
3057
|
this.element.shadowRoot.append(this.element.bib);
|
|
2615
3058
|
}
|
|
2616
|
-
|
|
3059
|
+
|
|
2617
3060
|
// Remove event & keyboard listeners
|
|
2618
3061
|
if (this.element?.trigger) {
|
|
2619
3062
|
this.element.trigger.removeEventListener('keydown', this.handleEvent);
|
|
@@ -3003,7 +3446,6 @@ var tokensCss$1$1 = css`:host{--ds-auro-dropdown-label-text-color: var(--ds-basi
|
|
|
3003
3446
|
|
|
3004
3447
|
const DESIGN_TOKEN_BREAKPOINT_PREFIX = '--ds-grid-breakpoint-';
|
|
3005
3448
|
const DESIGN_TOKEN_BREAKPOINT_OPTIONS = [
|
|
3006
|
-
'xl',
|
|
3007
3449
|
'lg',
|
|
3008
3450
|
'md',
|
|
3009
3451
|
'sm',
|
|
@@ -3075,7 +3517,6 @@ class AuroDropdownBib extends LitElement {
|
|
|
3075
3517
|
|
|
3076
3518
|
set mobileFullscreenBreakpoint(value) {
|
|
3077
3519
|
// verify the defined breakpoint is valid and exit out if not
|
|
3078
|
-
// 'disabled' is a design token breakpoint so it acts as our "undefined" value
|
|
3079
3520
|
const validatedValue = DESIGN_TOKEN_BREAKPOINT_OPTIONS.includes(value) ? value : undefined;
|
|
3080
3521
|
if (!validatedValue) {
|
|
3081
3522
|
this._mobileBreakpointValue = undefined;
|
|
@@ -3344,6 +3785,7 @@ var helpTextVersion$1 = '1.0.0';
|
|
|
3344
3785
|
* @csspart helpText - The helpText content container.
|
|
3345
3786
|
* @event auroDropdown-triggerClick - Notifies that the trigger has been clicked.
|
|
3346
3787
|
* @event auroDropdown-toggled - Notifies that the visibility of the dropdown bib has changed.
|
|
3788
|
+
* @event auroDropdown-idAdded - Notifies consumers that the unique ID for the dropdown bib has been generated.
|
|
3347
3789
|
*/
|
|
3348
3790
|
class AuroDropdown extends LitElement {
|
|
3349
3791
|
constructor() {
|
|
@@ -3389,7 +3831,9 @@ class AuroDropdown extends LitElement {
|
|
|
3389
3831
|
this.rounded = false;
|
|
3390
3832
|
this.tabIndex = 0;
|
|
3391
3833
|
this.noToggle = false;
|
|
3834
|
+
this.a11yAutocomplete = 'none';
|
|
3392
3835
|
this.labeled = true;
|
|
3836
|
+
this.a11yRole = 'combobox';
|
|
3393
3837
|
this.onDark = false;
|
|
3394
3838
|
|
|
3395
3839
|
// floaterConfig
|
|
@@ -3525,6 +3969,16 @@ class AuroDropdown extends LitElement {
|
|
|
3525
3969
|
type: Number
|
|
3526
3970
|
},
|
|
3527
3971
|
|
|
3972
|
+
/**
|
|
3973
|
+
* The unique ID for the dropdown bib element.
|
|
3974
|
+
* @private
|
|
3975
|
+
*/
|
|
3976
|
+
dropdownId: {
|
|
3977
|
+
type: String,
|
|
3978
|
+
reflect: false,
|
|
3979
|
+
attribute: false
|
|
3980
|
+
},
|
|
3981
|
+
|
|
3528
3982
|
/**
|
|
3529
3983
|
* If declared in combination with `bordered` property or `helpText` slot content, will apply red color to both.
|
|
3530
3984
|
*/
|
|
@@ -3588,12 +4042,7 @@ class AuroDropdown extends LitElement {
|
|
|
3588
4042
|
},
|
|
3589
4043
|
|
|
3590
4044
|
/**
|
|
3591
|
-
* Defines the screen size breakpoint (`
|
|
3592
|
-
* at which the dropdown switches to fullscreen mode on mobile. `disabled` indicates a dropdown should _never_ enter fullscreen.
|
|
3593
|
-
*
|
|
3594
|
-
* When expanded, the dropdown will automatically display in fullscreen mode
|
|
3595
|
-
* if the screen size is equal to or smaller than the selected breakpoint.
|
|
3596
|
-
* @default sm
|
|
4045
|
+
* Defines the screen size breakpoint (`lg`, `md`, `sm`, or `xs`) at which the dropdown switches to fullscreen mode on mobile. When expanded, the dropdown will automatically display in fullscreen mode if the screen size is equal to or smaller than the selected breakpoint.
|
|
3597
4046
|
*/
|
|
3598
4047
|
fullscreenBreakpoint: {
|
|
3599
4048
|
type: String,
|
|
@@ -3692,6 +4141,23 @@ class AuroDropdown extends LitElement {
|
|
|
3692
4141
|
*/
|
|
3693
4142
|
tabIndex: {
|
|
3694
4143
|
type: Number
|
|
4144
|
+
},
|
|
4145
|
+
|
|
4146
|
+
/**
|
|
4147
|
+
* The value for the role attribute of the trigger element.
|
|
4148
|
+
*/
|
|
4149
|
+
a11yRole: {
|
|
4150
|
+
type: String || undefined,
|
|
4151
|
+
attribute: false,
|
|
4152
|
+
reflect: false
|
|
4153
|
+
},
|
|
4154
|
+
|
|
4155
|
+
/**
|
|
4156
|
+
* The value for the aria-autocomplete attribute of the trigger element.
|
|
4157
|
+
*/
|
|
4158
|
+
a11yAutocomplete: {
|
|
4159
|
+
type: String,
|
|
4160
|
+
attribute: false,
|
|
3695
4161
|
}
|
|
3696
4162
|
};
|
|
3697
4163
|
}
|
|
@@ -3716,15 +4182,6 @@ class AuroDropdown extends LitElement {
|
|
|
3716
4182
|
AuroLibraryRuntimeUtils$1$2.prototype.registerComponent(name, AuroDropdown);
|
|
3717
4183
|
}
|
|
3718
4184
|
|
|
3719
|
-
/**
|
|
3720
|
-
* Accessor for reusing the focusable entity query string.
|
|
3721
|
-
* @private
|
|
3722
|
-
* @returns {string}
|
|
3723
|
-
*/
|
|
3724
|
-
get focusableEntityQuery () {
|
|
3725
|
-
return 'auro-input, [auro-input], auro-button, [auro-button], button, input';
|
|
3726
|
-
}
|
|
3727
|
-
|
|
3728
4185
|
connectedCallback() {
|
|
3729
4186
|
super.connectedCallback();
|
|
3730
4187
|
}
|
|
@@ -3738,8 +4195,6 @@ class AuroDropdown extends LitElement {
|
|
|
3738
4195
|
updated(changedProperties) {
|
|
3739
4196
|
this.floater.handleUpdate(changedProperties);
|
|
3740
4197
|
|
|
3741
|
-
// Note: `disabled` is not a breakpoint (it is not a screen size),
|
|
3742
|
-
// so it looks like we never consume this - however, dropdownBib handles this in the setter as "undefined"
|
|
3743
4198
|
if (changedProperties.has('fullscreenBreakpoint')) {
|
|
3744
4199
|
this.bibContent.mobileFullscreenBreakpoint = this.fullscreenBreakpoint;
|
|
3745
4200
|
}
|
|
@@ -3753,7 +4208,22 @@ class AuroDropdown extends LitElement {
|
|
|
3753
4208
|
}
|
|
3754
4209
|
|
|
3755
4210
|
firstUpdated() {
|
|
4211
|
+
|
|
4212
|
+
// Configure the floater to, this will generate the ID for the bib
|
|
3756
4213
|
this.floater.configure(this, 'auroDropdown');
|
|
4214
|
+
|
|
4215
|
+
/**
|
|
4216
|
+
* @description Let subscribers know that the dropdown ID ha been generated and added.
|
|
4217
|
+
* @event auroDropdown-idAdded
|
|
4218
|
+
* @type {Object<key: 'id', value: string>} - The ID of the dropdown bib element.
|
|
4219
|
+
*/
|
|
4220
|
+
this.dispatchEvent(new CustomEvent('auroDropdown-idAdded', {detail: {id: this.floater.element.id}}));
|
|
4221
|
+
|
|
4222
|
+
// Set the bib ID locally if the user hasn't provided a focusable trigger
|
|
4223
|
+
if (!this.triggerContentFocusable) {
|
|
4224
|
+
this.dropdownId = this.floater.element.id;
|
|
4225
|
+
}
|
|
4226
|
+
|
|
3757
4227
|
this.bibContent = this.floater.element.bib;
|
|
3758
4228
|
|
|
3759
4229
|
// Add the tag name as an attribute if it is different than the component name
|
|
@@ -3875,7 +4345,7 @@ class AuroDropdown extends LitElement {
|
|
|
3875
4345
|
|
|
3876
4346
|
this.triggerContentSlot.forEach((node) => {
|
|
3877
4347
|
if (node.querySelectorAll) {
|
|
3878
|
-
const auroElements = node.querySelectorAll(
|
|
4348
|
+
const auroElements = node.querySelectorAll('auro-input, [auro-input], auro-button, [auro-button], button, input');
|
|
3879
4349
|
auroElements.forEach((auroEl) => {
|
|
3880
4350
|
auroEl.addEventListener('focus', this.bindFocusEventToTrigger);
|
|
3881
4351
|
auroEl.addEventListener('blur', this.bindFocusEventToTrigger);
|
|
@@ -3896,7 +4366,7 @@ class AuroDropdown extends LitElement {
|
|
|
3896
4366
|
|
|
3897
4367
|
this.triggerContentSlot.forEach((node) => {
|
|
3898
4368
|
if (node.querySelectorAll) {
|
|
3899
|
-
const auroElements = node.querySelectorAll(
|
|
4369
|
+
const auroElements = node.querySelectorAll('auro-input, [auro-input], auro-button, [auro-button], button, input');
|
|
3900
4370
|
auroElements.forEach((auroEl) => {
|
|
3901
4371
|
auroEl.removeEventListener('focus', this.bindFocusEventToTrigger);
|
|
3902
4372
|
auroEl.removeEventListener('blur', this.bindFocusEventToTrigger);
|
|
@@ -3905,6 +4375,30 @@ class AuroDropdown extends LitElement {
|
|
|
3905
4375
|
});
|
|
3906
4376
|
}
|
|
3907
4377
|
|
|
4378
|
+
/*
|
|
4379
|
+
* Sets aria attributes for the trigger element if a custom one is passed in.
|
|
4380
|
+
* @private
|
|
4381
|
+
* @method setTriggerAriaAttributes
|
|
4382
|
+
* @param { HTMLElement } triggerElement - The custom trigger element.
|
|
4383
|
+
*/
|
|
4384
|
+
clearTriggerA11yAttributes(triggerElement) {
|
|
4385
|
+
|
|
4386
|
+
if (!triggerElement || !triggerElement.removeAttribute) {
|
|
4387
|
+
return;
|
|
4388
|
+
}
|
|
4389
|
+
|
|
4390
|
+
// Reset appropriate attributes for a11y
|
|
4391
|
+
triggerElement.removeAttribute('aria-labelledby');
|
|
4392
|
+
if (triggerElement.getAttribute('id') === `${this.id}-trigger-element`) {
|
|
4393
|
+
triggerElement.removeAttribute('id');
|
|
4394
|
+
}
|
|
4395
|
+
triggerElement.removeAttribute('role');
|
|
4396
|
+
triggerElement.removeAttribute('aria-expanded');
|
|
4397
|
+
|
|
4398
|
+
triggerElement.removeAttribute('aria-controls');
|
|
4399
|
+
triggerElement.removeAttribute('aria-autocomplete');
|
|
4400
|
+
}
|
|
4401
|
+
|
|
3908
4402
|
/**
|
|
3909
4403
|
* Handles changes to the trigger content slot and updates related properties.
|
|
3910
4404
|
*
|
|
@@ -3918,32 +4412,41 @@ class AuroDropdown extends LitElement {
|
|
|
3918
4412
|
* @returns {void}
|
|
3919
4413
|
*/
|
|
3920
4414
|
handleTriggerContentSlotChange(event) {
|
|
4415
|
+
|
|
3921
4416
|
this.floater.handleTriggerTabIndex();
|
|
3922
4417
|
|
|
4418
|
+
// Get the trigger
|
|
4419
|
+
const trigger = this.shadowRoot.querySelector('#trigger');
|
|
4420
|
+
|
|
4421
|
+
// Get the trigger slot
|
|
3923
4422
|
const triggerSlot = this.shadowRoot.querySelector('.triggerContent slot');
|
|
3924
4423
|
|
|
4424
|
+
// If there's a trigger slot
|
|
3925
4425
|
if (triggerSlot) {
|
|
3926
4426
|
|
|
4427
|
+
// Get the content nodes to see if there are any children
|
|
3927
4428
|
const triggerContentNodes = triggerSlot.assignedNodes();
|
|
3928
4429
|
|
|
4430
|
+
// If there are children
|
|
3929
4431
|
if (triggerContentNodes) {
|
|
3930
4432
|
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
this.triggerContentFocusable = this.containsFocusableElement(node);
|
|
3934
|
-
}
|
|
3935
|
-
});
|
|
3936
|
-
}
|
|
3937
|
-
}
|
|
4433
|
+
// See if any of them are focusable elemeents
|
|
4434
|
+
this.triggerContentFocusable = triggerContentNodes.some((node) => this.containsFocusableElement(node));
|
|
3938
4435
|
|
|
3939
|
-
|
|
4436
|
+
// If any of them are focusable elements
|
|
4437
|
+
if (this.triggerContentFocusable) {
|
|
3940
4438
|
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
4439
|
+
// Assume the consumer will be providing their own a11y in whatever they passed in
|
|
4440
|
+
this.clearTriggerA11yAttributes(trigger);
|
|
4441
|
+
|
|
4442
|
+
// Remove the tabindex from the trigger so it doesn't interrupt focus flow
|
|
4443
|
+
trigger.removeAttribute('tabindex');
|
|
4444
|
+
} else {
|
|
4445
|
+
|
|
4446
|
+
// Add the tabindex to the trigger so that it's in the focus flow
|
|
4447
|
+
trigger.setAttribute('tabindex', '0');
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
3947
4450
|
}
|
|
3948
4451
|
|
|
3949
4452
|
if (event) {
|
|
@@ -3953,6 +4456,7 @@ class AuroDropdown extends LitElement {
|
|
|
3953
4456
|
|
|
3954
4457
|
if (this.triggerContentSlot) {
|
|
3955
4458
|
this.setupTriggerFocusEventBinding();
|
|
4459
|
+
|
|
3956
4460
|
this.hasTriggerContent = this.triggerContentSlot.some((slot) => {
|
|
3957
4461
|
if (slot.textContent.trim()) {
|
|
3958
4462
|
return true;
|
|
@@ -4020,10 +4524,13 @@ class AuroDropdown extends LitElement {
|
|
|
4020
4524
|
id="trigger"
|
|
4021
4525
|
class="trigger"
|
|
4022
4526
|
part="trigger"
|
|
4023
|
-
aria-labelledby="triggerLabel"
|
|
4024
4527
|
tabindex="${this.tabIndex}"
|
|
4025
4528
|
?showBorder="${this.showTriggerBorders}"
|
|
4026
|
-
|
|
4529
|
+
role="${ifDefined(this.triggerContentFocusable ? undefined : this.a11yRole)}"
|
|
4530
|
+
aria-expanded="${ifDefined(this.triggerContentFocusable ? undefined : this.isPopoverVisible)}"
|
|
4531
|
+
aria-controls="${ifDefined(this.triggerContentFocusable ? undefined : this.dropdownId)}"
|
|
4532
|
+
aria-labelledby="${ifDefined(this.triggerContentFocusable ? undefined : 'triggerLabel')}"
|
|
4533
|
+
>
|
|
4027
4534
|
<div class="triggerContentWrapper">
|
|
4028
4535
|
<label class="label" id="triggerLabel" hasTrigger=${this.hasTriggerContent}>
|
|
4029
4536
|
<slot name="label" @slotchange="${this.handleLabelSlotChange}"></slot>
|
|
@@ -4057,12 +4564,12 @@ class AuroDropdown extends LitElement {
|
|
|
4057
4564
|
<div id="bibSizer" part="size"></div>
|
|
4058
4565
|
<${this.dropdownBibTag}
|
|
4059
4566
|
id="bib"
|
|
4060
|
-
role="tooltip"
|
|
4061
4567
|
?data-show="${this.isPopoverVisible}"
|
|
4062
4568
|
?isfullscreen="${this.isBibFullscreen}"
|
|
4063
4569
|
?common="${this.common}"
|
|
4064
4570
|
?rounded="${this.common || this.rounded}"
|
|
4065
|
-
?inset="${this.common || this.inset}"
|
|
4571
|
+
?inset="${this.common || this.inset}"
|
|
4572
|
+
>
|
|
4066
4573
|
</${this.dropdownBibTag}>
|
|
4067
4574
|
</div>
|
|
4068
4575
|
`;
|
|
@@ -8040,6 +8547,414 @@ class AuroInputUtilities {
|
|
|
8040
8547
|
}
|
|
8041
8548
|
}
|
|
8042
8549
|
|
|
8550
|
+
class DateFormatter {
|
|
8551
|
+
|
|
8552
|
+
constructor() {
|
|
8553
|
+
|
|
8554
|
+
/**
|
|
8555
|
+
* @description Parses a date string into its components.
|
|
8556
|
+
* @param {string} dateStr - Date string to parse.
|
|
8557
|
+
* @param {string} format - Date format to parse.
|
|
8558
|
+
* @returns {Object<key["month" | "day" | "year"]: number>|undefined}
|
|
8559
|
+
*/
|
|
8560
|
+
this.parseDate = (dateStr, format = 'mm/dd/yyyy') => {
|
|
8561
|
+
|
|
8562
|
+
// Guard Clause: Date string is defined
|
|
8563
|
+
if (!dateStr) {
|
|
8564
|
+
return undefined;
|
|
8565
|
+
}
|
|
8566
|
+
|
|
8567
|
+
// Assume the separator is a "/" a defined in our code base
|
|
8568
|
+
const separator = '/';
|
|
8569
|
+
|
|
8570
|
+
// Get the parts of the date and format
|
|
8571
|
+
const valueParts = dateStr.split(separator);
|
|
8572
|
+
const formatParts = format.split(separator);
|
|
8573
|
+
|
|
8574
|
+
// Check if the value and format have the correct number of parts
|
|
8575
|
+
if (valueParts.length !== formatParts.length) {
|
|
8576
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Date string and format length do not match');
|
|
8577
|
+
}
|
|
8578
|
+
|
|
8579
|
+
// Holds the result to be returned
|
|
8580
|
+
const result = formatParts.reduce((acc, part, index) => {
|
|
8581
|
+
const value = valueParts[index];
|
|
8582
|
+
|
|
8583
|
+
if ((/m/iu).test(part)) {
|
|
8584
|
+
acc.month = value;
|
|
8585
|
+
} else if ((/d/iu).test(part)) {
|
|
8586
|
+
acc.day = value;
|
|
8587
|
+
} else if ((/y/iu).test(part)) {
|
|
8588
|
+
acc.year = value;
|
|
8589
|
+
}
|
|
8590
|
+
|
|
8591
|
+
return acc;
|
|
8592
|
+
}, {});
|
|
8593
|
+
|
|
8594
|
+
// If we found all the parts, return the result
|
|
8595
|
+
if (result.month && result.year) {
|
|
8596
|
+
return result;
|
|
8597
|
+
}
|
|
8598
|
+
|
|
8599
|
+
// Throw an error to let the dev know we were unable to parse the date string
|
|
8600
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Unable to parse date string');
|
|
8601
|
+
};
|
|
8602
|
+
|
|
8603
|
+
/**
|
|
8604
|
+
* Convert a date object to string format.
|
|
8605
|
+
* @param {Object} date - Date to convert to string.
|
|
8606
|
+
* @returns {Object} Returns the date as a string.
|
|
8607
|
+
*/
|
|
8608
|
+
this.getDateAsString = (date) => date.toLocaleDateString(undefined, {
|
|
8609
|
+
year: "numeric",
|
|
8610
|
+
month: "2-digit",
|
|
8611
|
+
day: "2-digit",
|
|
8612
|
+
});
|
|
8613
|
+
|
|
8614
|
+
/**
|
|
8615
|
+
* Converts a date string to a North American date format.
|
|
8616
|
+
* @param {String} dateStr - Date to validate.
|
|
8617
|
+
* @param {String} format - Date format to validate against.
|
|
8618
|
+
* @returns {Boolean}
|
|
8619
|
+
*/
|
|
8620
|
+
this.toNorthAmericanFormat = (dateStr, format) => {
|
|
8621
|
+
|
|
8622
|
+
if (format === 'mm/dd/yyyy') {
|
|
8623
|
+
return dateStr;
|
|
8624
|
+
}
|
|
8625
|
+
|
|
8626
|
+
const parsedDate = this.parseDate(dateStr, format);
|
|
8627
|
+
|
|
8628
|
+
if (!parsedDate) {
|
|
8629
|
+
throw new Error('AuroDatepickerUtilities | toNorthAmericanFormat: Unable to parse date string');
|
|
8630
|
+
}
|
|
8631
|
+
|
|
8632
|
+
const { month, day, year } = parsedDate;
|
|
8633
|
+
|
|
8634
|
+
const dateParts = [];
|
|
8635
|
+
if (month) {
|
|
8636
|
+
dateParts.push(month);
|
|
8637
|
+
}
|
|
8638
|
+
|
|
8639
|
+
if (day) {
|
|
8640
|
+
dateParts.push(day);
|
|
8641
|
+
}
|
|
8642
|
+
|
|
8643
|
+
if (year) {
|
|
8644
|
+
dateParts.push(year);
|
|
8645
|
+
}
|
|
8646
|
+
|
|
8647
|
+
return dateParts.join('/');
|
|
8648
|
+
};
|
|
8649
|
+
}
|
|
8650
|
+
}
|
|
8651
|
+
const dateFormatter = new DateFormatter();
|
|
8652
|
+
|
|
8653
|
+
// filepath: dateConstraints.mjs
|
|
8654
|
+
const DATE_UTIL_CONSTRAINTS = {
|
|
8655
|
+
maxDay: 31,
|
|
8656
|
+
maxMonth: 12,
|
|
8657
|
+
maxYear: 2400,
|
|
8658
|
+
minDay: 1,
|
|
8659
|
+
minMonth: 1,
|
|
8660
|
+
minYear: 1900,
|
|
8661
|
+
};
|
|
8662
|
+
|
|
8663
|
+
class AuroDateUtilitiesBase {
|
|
8664
|
+
|
|
8665
|
+
/**
|
|
8666
|
+
* @description The maximum day value allowed by the various utilities in this class.
|
|
8667
|
+
* @readonly
|
|
8668
|
+
* @type {Number}
|
|
8669
|
+
*/
|
|
8670
|
+
get maxDay() {
|
|
8671
|
+
return DATE_UTIL_CONSTRAINTS.maxDay;
|
|
8672
|
+
}
|
|
8673
|
+
|
|
8674
|
+
/**
|
|
8675
|
+
* @description The maximum month value allowed by the various utilities in this class.
|
|
8676
|
+
* @readonly
|
|
8677
|
+
* @type {Number}
|
|
8678
|
+
*/
|
|
8679
|
+
get maxMonth() {
|
|
8680
|
+
return DATE_UTIL_CONSTRAINTS.maxMonth;
|
|
8681
|
+
}
|
|
8682
|
+
|
|
8683
|
+
/**
|
|
8684
|
+
* @description The maximum year value allowed by the various utilities in this class.
|
|
8685
|
+
* @readonly
|
|
8686
|
+
* @type {Number}
|
|
8687
|
+
*/
|
|
8688
|
+
get maxYear() {
|
|
8689
|
+
return DATE_UTIL_CONSTRAINTS.maxYear;
|
|
8690
|
+
}
|
|
8691
|
+
|
|
8692
|
+
/**
|
|
8693
|
+
* @description The minimum day value allowed by the various utilities in this class.
|
|
8694
|
+
* @readonly
|
|
8695
|
+
* @type {Number}
|
|
8696
|
+
*/
|
|
8697
|
+
get minDay() {
|
|
8698
|
+
return DATE_UTIL_CONSTRAINTS.minDay;
|
|
8699
|
+
}
|
|
8700
|
+
|
|
8701
|
+
/**
|
|
8702
|
+
* @description The minimum month value allowed by the various utilities in this class.
|
|
8703
|
+
* @readonly
|
|
8704
|
+
* @type {Number}
|
|
8705
|
+
*/
|
|
8706
|
+
get minMonth() {
|
|
8707
|
+
return DATE_UTIL_CONSTRAINTS.minMonth;
|
|
8708
|
+
}
|
|
8709
|
+
|
|
8710
|
+
/**
|
|
8711
|
+
* @description The minimum year value allowed by the various utilities in this class.
|
|
8712
|
+
* @readonly
|
|
8713
|
+
* @type {Number}
|
|
8714
|
+
*/
|
|
8715
|
+
get minYear() {
|
|
8716
|
+
return DATE_UTIL_CONSTRAINTS.minYear;
|
|
8717
|
+
}
|
|
8718
|
+
}
|
|
8719
|
+
|
|
8720
|
+
/* eslint-disable no-magic-numbers */
|
|
8721
|
+
|
|
8722
|
+
class AuroDateUtilities extends AuroDateUtilitiesBase {
|
|
8723
|
+
|
|
8724
|
+
/**
|
|
8725
|
+
* Returns the current century.
|
|
8726
|
+
* @returns {String} The current century.
|
|
8727
|
+
*/
|
|
8728
|
+
getCentury () {
|
|
8729
|
+
return String(new Date().getFullYear()).slice(0, 2);
|
|
8730
|
+
}
|
|
8731
|
+
|
|
8732
|
+
/**
|
|
8733
|
+
* Returns a four digit year.
|
|
8734
|
+
* @param {String} year - The year to convert to four digits.
|
|
8735
|
+
* @returns {String} The four digit year.
|
|
8736
|
+
*/
|
|
8737
|
+
getFourDigitYear (year) {
|
|
8738
|
+
|
|
8739
|
+
const strYear = String(year).trim();
|
|
8740
|
+
return strYear.length <= 2 ? this.getCentury() + strYear : strYear;
|
|
8741
|
+
}
|
|
8742
|
+
|
|
8743
|
+
constructor() {
|
|
8744
|
+
|
|
8745
|
+
super();
|
|
8746
|
+
|
|
8747
|
+
/**
|
|
8748
|
+
* Compares two dates to see if they match.
|
|
8749
|
+
* @param {Object} date1 - First date to compare.
|
|
8750
|
+
* @param {Object} date2 - Second date to compare.
|
|
8751
|
+
* @returns {Boolean} Returns true if the dates match.
|
|
8752
|
+
*/
|
|
8753
|
+
this.datesMatch = (date1, date2) => new Date(date1).getTime() === new Date(date2).getTime();
|
|
8754
|
+
|
|
8755
|
+
/**
|
|
8756
|
+
* Returns true if value passed in is a valid date.
|
|
8757
|
+
* @param {String} date - Date to validate.
|
|
8758
|
+
* @param {String} format - Date format to validate against.
|
|
8759
|
+
* @returns {Boolean}
|
|
8760
|
+
*/
|
|
8761
|
+
this.validDateStr = (date, format) => {
|
|
8762
|
+
|
|
8763
|
+
// The length we expect the date string to be
|
|
8764
|
+
const dateStrLength = format.length;
|
|
8765
|
+
|
|
8766
|
+
// Guard Clause: Date and format are defined
|
|
8767
|
+
if (typeof date === "undefined" || typeof format === "undefined") {
|
|
8768
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date and format are required');
|
|
8769
|
+
}
|
|
8770
|
+
|
|
8771
|
+
// Guard Clause: Date should be of type string
|
|
8772
|
+
if (typeof date !== "string") {
|
|
8773
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date must be a string');
|
|
8774
|
+
}
|
|
8775
|
+
|
|
8776
|
+
// Guard Clause: Format should be of type string
|
|
8777
|
+
if (typeof format !== "string") {
|
|
8778
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Format must be a string');
|
|
8779
|
+
}
|
|
8780
|
+
|
|
8781
|
+
// Guard Clause: Length is what we expect it to be
|
|
8782
|
+
if (date.length !== dateStrLength) {
|
|
8783
|
+
return false;
|
|
8784
|
+
}
|
|
8785
|
+
// Get a formatted date string and parse it
|
|
8786
|
+
const dateParts = dateFormatter.parseDate(date, format);
|
|
8787
|
+
|
|
8788
|
+
// Guard Clause: Date parse succeeded
|
|
8789
|
+
if (!dateParts) {
|
|
8790
|
+
return false;
|
|
8791
|
+
}
|
|
8792
|
+
|
|
8793
|
+
// Create the expected date string based on the date parts
|
|
8794
|
+
const expectedDateStr = `${dateParts.month}/${dateParts.day || "01"}/${this.getFourDigitYear(dateParts.year)}`;
|
|
8795
|
+
|
|
8796
|
+
// Generate a date object that we will extract a string date from to compare to the passed in date string
|
|
8797
|
+
const dateObj = new Date(this.getFourDigitYear(dateParts.year), dateParts.month - 1, dateParts.day || 1);
|
|
8798
|
+
|
|
8799
|
+
// Get the date string of the date object we created from the string date
|
|
8800
|
+
const actualDateStr = dateFormatter.getDateAsString(dateObj);
|
|
8801
|
+
|
|
8802
|
+
// Guard Clause: Generated date matches date string input
|
|
8803
|
+
if (expectedDateStr !== actualDateStr) {
|
|
8804
|
+
return false;
|
|
8805
|
+
}
|
|
8806
|
+
|
|
8807
|
+
// If we passed all other checks, we can assume the date is valid
|
|
8808
|
+
return true;
|
|
8809
|
+
};
|
|
8810
|
+
|
|
8811
|
+
/**
|
|
8812
|
+
* Determines if a string date value matches the format provided.
|
|
8813
|
+
* @param {string} value = The date string value.
|
|
8814
|
+
* @param { string} format = The date format to match against.
|
|
8815
|
+
* @returns {boolean}
|
|
8816
|
+
*/
|
|
8817
|
+
this.dateAndFormatMatch = (value, format) => {
|
|
8818
|
+
|
|
8819
|
+
// Ensure we have both values we need to do the comparison
|
|
8820
|
+
if (!value || !format) {
|
|
8821
|
+
throw new Error('AuroFormValidation | dateFormatMatch: value and format are required');
|
|
8822
|
+
}
|
|
8823
|
+
|
|
8824
|
+
// If the lengths are different, they cannot match
|
|
8825
|
+
if (value.length !== format.length) {
|
|
8826
|
+
return false;
|
|
8827
|
+
}
|
|
8828
|
+
|
|
8829
|
+
// Get the parts of the date
|
|
8830
|
+
const dateParts = dateFormatter.parseDate(value, format);
|
|
8831
|
+
|
|
8832
|
+
// Validator for day
|
|
8833
|
+
const dayValueIsValid = (day) => {
|
|
8834
|
+
|
|
8835
|
+
// Guard clause: if there is no day in the dateParts, we can ignore this check.
|
|
8836
|
+
if (!dateParts.day) {
|
|
8837
|
+
return true;
|
|
8838
|
+
}
|
|
8839
|
+
|
|
8840
|
+
// Guard clause: ensure day exists.
|
|
8841
|
+
if (!day) {
|
|
8842
|
+
return false;
|
|
8843
|
+
}
|
|
8844
|
+
|
|
8845
|
+
// Convert day to number
|
|
8846
|
+
const numDay = Number.parseInt(day, 10);
|
|
8847
|
+
|
|
8848
|
+
// Guard clause: ensure day is a valid integer
|
|
8849
|
+
if (Number.isNaN(numDay)) {
|
|
8850
|
+
throw new Error('AuroDatepickerUtilities | dayValueIsValid: Unable to parse day value integer');
|
|
8851
|
+
}
|
|
8852
|
+
|
|
8853
|
+
// Guard clause: ensure day is within the valid range
|
|
8854
|
+
if (numDay < this.minDay || numDay > this.maxDay) {
|
|
8855
|
+
return false;
|
|
8856
|
+
}
|
|
8857
|
+
|
|
8858
|
+
// Default return
|
|
8859
|
+
return true;
|
|
8860
|
+
};
|
|
8861
|
+
|
|
8862
|
+
// Validator for month
|
|
8863
|
+
const monthValueIsValid = (month) => {
|
|
8864
|
+
|
|
8865
|
+
// Guard clause: ensure month exists.
|
|
8866
|
+
if (!month) {
|
|
8867
|
+
return false;
|
|
8868
|
+
}
|
|
8869
|
+
|
|
8870
|
+
// Convert month to number
|
|
8871
|
+
const numMonth = Number.parseInt(month, 10);
|
|
8872
|
+
|
|
8873
|
+
// Guard clause: ensure month is a valid integer
|
|
8874
|
+
if (Number.isNaN(numMonth)) {
|
|
8875
|
+
throw new Error('AuroDatepickerUtilities | monthValueIsValid: Unable to parse month value integer');
|
|
8876
|
+
}
|
|
8877
|
+
|
|
8878
|
+
// Guard clause: ensure month is within the valid range
|
|
8879
|
+
if (numMonth < this.minMonth || numMonth > this.maxMonth) {
|
|
8880
|
+
return false;
|
|
8881
|
+
}
|
|
8882
|
+
|
|
8883
|
+
// Default return
|
|
8884
|
+
return true;
|
|
8885
|
+
};
|
|
8886
|
+
|
|
8887
|
+
// Validator for year
|
|
8888
|
+
const yearIsValid = (_year) => {
|
|
8889
|
+
|
|
8890
|
+
// Guard clause: ensure year exists.
|
|
8891
|
+
if (!_year) {
|
|
8892
|
+
return false;
|
|
8893
|
+
}
|
|
8894
|
+
|
|
8895
|
+
// Get the full year
|
|
8896
|
+
const year = this.getFourDigitYear(_year);
|
|
8897
|
+
|
|
8898
|
+
// Convert year to number
|
|
8899
|
+
const numYear = Number.parseInt(year, 10);
|
|
8900
|
+
|
|
8901
|
+
// Guard clause: ensure year is a valid integer
|
|
8902
|
+
if (Number.isNaN(numYear)) {
|
|
8903
|
+
throw new Error('AuroDatepickerUtilities | yearValueIsValid: Unable to parse year value integer');
|
|
8904
|
+
}
|
|
8905
|
+
|
|
8906
|
+
// Guard clause: ensure year is within the valid range
|
|
8907
|
+
if (numYear < this.minYear || numYear > this.maxYear) {
|
|
8908
|
+
return false;
|
|
8909
|
+
}
|
|
8910
|
+
|
|
8911
|
+
// Default return
|
|
8912
|
+
return true;
|
|
8913
|
+
};
|
|
8914
|
+
|
|
8915
|
+
// Self-contained checks for month, day, and year
|
|
8916
|
+
const checks = [
|
|
8917
|
+
monthValueIsValid(dateParts.month),
|
|
8918
|
+
dayValueIsValid(dateParts.day),
|
|
8919
|
+
yearIsValid(dateParts.year)
|
|
8920
|
+
];
|
|
8921
|
+
|
|
8922
|
+
// If any of the checks failed, the date format does not match and the result is invalid
|
|
8923
|
+
const isValid = checks.every((check) => check === true);
|
|
8924
|
+
|
|
8925
|
+
// If the check is invalid, return false
|
|
8926
|
+
if (!isValid) {
|
|
8927
|
+
return false;
|
|
8928
|
+
}
|
|
8929
|
+
|
|
8930
|
+
// Default case
|
|
8931
|
+
return true;
|
|
8932
|
+
};
|
|
8933
|
+
}
|
|
8934
|
+
}
|
|
8935
|
+
|
|
8936
|
+
// Export a class instance
|
|
8937
|
+
const dateUtilities = new AuroDateUtilities();
|
|
8938
|
+
|
|
8939
|
+
// Export the class instance methods individually
|
|
8940
|
+
const {
|
|
8941
|
+
datesMatch,
|
|
8942
|
+
validDateStr,
|
|
8943
|
+
dateAndFormatMatch,
|
|
8944
|
+
minDay,
|
|
8945
|
+
minMonth,
|
|
8946
|
+
minYear,
|
|
8947
|
+
maxDay,
|
|
8948
|
+
maxMonth,
|
|
8949
|
+
maxYear
|
|
8950
|
+
} = dateUtilities;
|
|
8951
|
+
|
|
8952
|
+
const {
|
|
8953
|
+
toNorthAmericanFormat,
|
|
8954
|
+
parseDate,
|
|
8955
|
+
getDateAsString
|
|
8956
|
+
} = dateFormatter;
|
|
8957
|
+
|
|
8043
8958
|
// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
8044
8959
|
// See LICENSE in the project root for license information.
|
|
8045
8960
|
|
|
@@ -8115,6 +9030,7 @@ let AuroLibraryRuntimeUtils$1$1 = class AuroLibraryRuntimeUtils {
|
|
|
8115
9030
|
|
|
8116
9031
|
|
|
8117
9032
|
class AuroFormValidation {
|
|
9033
|
+
|
|
8118
9034
|
constructor() {
|
|
8119
9035
|
this.runtimeUtils = new AuroLibraryRuntimeUtils$1$1();
|
|
8120
9036
|
}
|
|
@@ -8206,17 +9122,17 @@ class AuroFormValidation {
|
|
|
8206
9122
|
]
|
|
8207
9123
|
}
|
|
8208
9124
|
};
|
|
8209
|
-
|
|
9125
|
+
|
|
8210
9126
|
let elementType;
|
|
8211
9127
|
if (this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
8212
9128
|
elementType = 'input';
|
|
8213
9129
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-counter') || this.runtimeUtils.elementMatch(elem, 'auro-counter-group')) {
|
|
8214
9130
|
elementType = 'counter';
|
|
8215
9131
|
}
|
|
8216
|
-
|
|
9132
|
+
|
|
8217
9133
|
if (elementType) {
|
|
8218
9134
|
const rules = validationRules[elementType];
|
|
8219
|
-
|
|
9135
|
+
|
|
8220
9136
|
if (rules) {
|
|
8221
9137
|
Object.values(rules).flat().forEach(rule => {
|
|
8222
9138
|
if (rule.check(elem)) {
|
|
@@ -8242,48 +9158,82 @@ class AuroFormValidation {
|
|
|
8242
9158
|
if (!elem.value.match(emailRegex)) {
|
|
8243
9159
|
elem.validity = 'patternMismatch';
|
|
8244
9160
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
9161
|
+
return;
|
|
8245
9162
|
}
|
|
8246
9163
|
} else if (elem.type === 'credit-card') {
|
|
8247
9164
|
if (elem.value.length > 0 && elem.value.length < elem.validationCCLength) {
|
|
8248
9165
|
elem.validity = 'tooShort';
|
|
8249
9166
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
9167
|
+
return;
|
|
8250
9168
|
}
|
|
8251
9169
|
} else if (elem.type === 'number') {
|
|
8252
9170
|
if (elem.max !== undefined && Number(elem.max) < Number(elem.value)) {
|
|
8253
9171
|
elem.validity = 'rangeOverflow';
|
|
8254
9172
|
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
9173
|
+
return;
|
|
8255
9174
|
}
|
|
8256
9175
|
|
|
8257
9176
|
if (elem.min !== undefined && elem.value?.length > 0 && Number(elem.min) > Number(elem.value)) {
|
|
8258
9177
|
elem.validity = 'rangeUnderflow';
|
|
8259
9178
|
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
9179
|
+
return;
|
|
8260
9180
|
}
|
|
8261
|
-
} else if (elem.type === 'date') {
|
|
8262
|
-
|
|
9181
|
+
} else if (elem.type === 'date' && elem.value?.length > 0) {
|
|
9182
|
+
|
|
9183
|
+
// Guard Clause: if the value is too short
|
|
9184
|
+
if (elem.value.length < elem.lengthForType) {
|
|
9185
|
+
|
|
8263
9186
|
elem.validity = 'tooShort';
|
|
8264
9187
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
9188
|
+
return;
|
|
9189
|
+
}
|
|
9190
|
+
|
|
9191
|
+
// Guard Clause: If the value is too long for the type
|
|
9192
|
+
if (elem.value?.length > elem.lengthForType) {
|
|
9193
|
+
|
|
9194
|
+
elem.validity = 'tooLong';
|
|
9195
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
9196
|
+
return;
|
|
9197
|
+
}
|
|
9198
|
+
|
|
9199
|
+
// Validate that the date passed was the correct format
|
|
9200
|
+
if (!dateAndFormatMatch(elem.value, elem.format)) {
|
|
9201
|
+
elem.validity = 'patternMismatch';
|
|
9202
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || 'Invalid Date Format Entered';
|
|
9203
|
+
return;
|
|
9204
|
+
}
|
|
9205
|
+
|
|
9206
|
+
// Validate that the date passed was a valid date
|
|
9207
|
+
if (!validDateStr(elem.value, elem.format)) {
|
|
9208
|
+
elem.validity = 'invalidDate';
|
|
9209
|
+
elem.errorMessage = elem.setCustomValidityInvalidDate || elem.setCustomValidity || 'Invalid Date Entered';
|
|
9210
|
+
return;
|
|
9211
|
+
}
|
|
8268
9212
|
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
9213
|
+
// Perform the rest of the validation
|
|
9214
|
+
const formattedValue = toNorthAmericanFormat(elem.value, elem.format);
|
|
9215
|
+
const valueDate = new Date(formattedValue);
|
|
8272
9216
|
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
9217
|
+
// // Validate max date
|
|
9218
|
+
if (elem.max?.length === elem.lengthForType) {
|
|
9219
|
+
|
|
9220
|
+
const maxDate = new Date(toNorthAmericanFormat(elem.max, elem.format));
|
|
9221
|
+
|
|
9222
|
+
if (valueDate > maxDate) {
|
|
9223
|
+
elem.validity = 'rangeOverflow';
|
|
9224
|
+
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
9225
|
+
return;
|
|
8277
9226
|
}
|
|
9227
|
+
}
|
|
8278
9228
|
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
9229
|
+
// Validate min date
|
|
9230
|
+
if (elem.min?.length === elem.lengthForType) {
|
|
9231
|
+
const minDate = new Date(toNorthAmericanFormat(elem.min, elem.format));
|
|
8282
9232
|
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
9233
|
+
if (valueDate < minDate) {
|
|
9234
|
+
elem.validity = 'rangeUnderflow';
|
|
9235
|
+
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
9236
|
+
return;
|
|
8287
9237
|
}
|
|
8288
9238
|
}
|
|
8289
9239
|
}
|
|
@@ -8402,7 +9352,7 @@ class AuroFormValidation {
|
|
|
8402
9352
|
if (input.validationMessage.length > 0) {
|
|
8403
9353
|
elem.errorMessage = input.validationMessage;
|
|
8404
9354
|
}
|
|
8405
|
-
} else if (this.inputElements?.length > 0
|
|
9355
|
+
} else if (this.inputElements?.length > 0 && elem.errorMessage === '') {
|
|
8406
9356
|
const firstInput = this.inputElements[0];
|
|
8407
9357
|
|
|
8408
9358
|
if (firstInput.validationMessage.length > 0) {
|
|
@@ -8524,6 +9474,33 @@ class BaseInput extends LitElement {
|
|
|
8524
9474
|
static get properties() {
|
|
8525
9475
|
return {
|
|
8526
9476
|
|
|
9477
|
+
/**
|
|
9478
|
+
* The value for the role attribute.
|
|
9479
|
+
*/
|
|
9480
|
+
a11yRole: {
|
|
9481
|
+
type: String,
|
|
9482
|
+
attribute: true,
|
|
9483
|
+
reflect: true
|
|
9484
|
+
},
|
|
9485
|
+
|
|
9486
|
+
/**
|
|
9487
|
+
* The value for the aria-expanded attribute.
|
|
9488
|
+
*/
|
|
9489
|
+
a11yExpanded: {
|
|
9490
|
+
type: Boolean,
|
|
9491
|
+
attribute: true,
|
|
9492
|
+
reflect: true
|
|
9493
|
+
},
|
|
9494
|
+
|
|
9495
|
+
/**
|
|
9496
|
+
* The value for the aria-controls attribute.
|
|
9497
|
+
*/
|
|
9498
|
+
a11yControls: {
|
|
9499
|
+
type: String,
|
|
9500
|
+
attribute: true,
|
|
9501
|
+
reflect: true
|
|
9502
|
+
},
|
|
9503
|
+
|
|
8527
9504
|
/**
|
|
8528
9505
|
* If set, the label will remain fixed in the active position.
|
|
8529
9506
|
*/
|
|
@@ -9165,6 +10142,10 @@ class BaseInput extends LitElement {
|
|
|
9165
10142
|
} else if (this.type === 'number') {
|
|
9166
10143
|
this.inputMode = 'numeric';
|
|
9167
10144
|
}
|
|
10145
|
+
|
|
10146
|
+
if (this.type === "date" && !this.format) {
|
|
10147
|
+
this.format = 'mm/dd/yyyy';
|
|
10148
|
+
}
|
|
9168
10149
|
}
|
|
9169
10150
|
|
|
9170
10151
|
/**
|
|
@@ -10408,6 +11389,7 @@ var helpTextVersion = '1.0.0';
|
|
|
10408
11389
|
|
|
10409
11390
|
// build the component class
|
|
10410
11391
|
class AuroInput extends BaseInput {
|
|
11392
|
+
|
|
10411
11393
|
constructor() {
|
|
10412
11394
|
super();
|
|
10413
11395
|
|
|
@@ -10520,7 +11502,7 @@ class AuroInput extends BaseInput {
|
|
|
10520
11502
|
?required="${this.required}"
|
|
10521
11503
|
?disabled="${this.disabled}"
|
|
10522
11504
|
aria-describedby="${this.uniqueId}"
|
|
10523
|
-
aria-invalid="${this.validity !== 'valid'}"
|
|
11505
|
+
?aria-invalid="${this.validity !== 'valid'}"
|
|
10524
11506
|
placeholder=${this.getPlaceholder()}
|
|
10525
11507
|
lang="${ifDefined(this.lang)}"
|
|
10526
11508
|
?activeLabel="${this.activeLabel}"
|
|
@@ -10529,7 +11511,10 @@ class AuroInput extends BaseInput {
|
|
|
10529
11511
|
autocapitalize="${ifDefined(this.autocapitalize ? this.autocapitalize : undefined)}"
|
|
10530
11512
|
autocomplete="${ifDefined(this.autocomplete ? this.autocomplete : undefined)}"
|
|
10531
11513
|
part="input"
|
|
10532
|
-
|
|
11514
|
+
role="${ifDefined(this.a11yRole)}"
|
|
11515
|
+
aria-expanded="${ifDefined(this.a11yExpanded)}"
|
|
11516
|
+
aria-controls="${ifDefined(this.a11yControls)}"
|
|
11517
|
+
/>
|
|
10533
11518
|
</div>
|
|
10534
11519
|
<div
|
|
10535
11520
|
class="notificationIcons"
|
|
@@ -11521,6 +12506,7 @@ var styleCss = css`.util_displayInline{display:inline}.util_displayInlineBlock{d
|
|
|
11521
12506
|
|
|
11522
12507
|
// build the component class
|
|
11523
12508
|
class AuroCombobox extends LitElement {
|
|
12509
|
+
|
|
11524
12510
|
constructor() {
|
|
11525
12511
|
super();
|
|
11526
12512
|
|
|
@@ -11532,6 +12518,8 @@ class AuroCombobox extends LitElement {
|
|
|
11532
12518
|
* @returns {void} Internal defaults.
|
|
11533
12519
|
*/
|
|
11534
12520
|
privateDefaults() {
|
|
12521
|
+
this.dropdownOpen = false;
|
|
12522
|
+
this.dropdownId = undefined;
|
|
11535
12523
|
this.onDark = false;
|
|
11536
12524
|
|
|
11537
12525
|
this.noFilter = false;
|
|
@@ -11611,6 +12599,26 @@ class AuroCombobox extends LitElement {
|
|
|
11611
12599
|
reflect: true
|
|
11612
12600
|
},
|
|
11613
12601
|
|
|
12602
|
+
/**
|
|
12603
|
+
* ID for the dropdown
|
|
12604
|
+
* @private
|
|
12605
|
+
*/
|
|
12606
|
+
dropdownId: {
|
|
12607
|
+
type: String,
|
|
12608
|
+
reflect: false,
|
|
12609
|
+
attribute: false
|
|
12610
|
+
},
|
|
12611
|
+
|
|
12612
|
+
/**
|
|
12613
|
+
* Whether or not the dropdown is open
|
|
12614
|
+
* @private
|
|
12615
|
+
*/
|
|
12616
|
+
dropdownOpen: {
|
|
12617
|
+
type: Boolean,
|
|
12618
|
+
reflect: false,
|
|
12619
|
+
attribute: false
|
|
12620
|
+
},
|
|
12621
|
+
|
|
11614
12622
|
/**
|
|
11615
12623
|
* When defined, sets persistent validity to `customError` and sets the validation message to the attribute value.
|
|
11616
12624
|
*/
|
|
@@ -11756,11 +12764,8 @@ class AuroCombobox extends LitElement {
|
|
|
11756
12764
|
},
|
|
11757
12765
|
|
|
11758
12766
|
/**
|
|
11759
|
-
* Defines the screen size breakpoint (`
|
|
11760
|
-
*
|
|
11761
|
-
*
|
|
11762
|
-
* When expanded, the dropdown will automatically display in fullscreen mode
|
|
11763
|
-
* if the screen size is equal to or smaller than the selected breakpoint.
|
|
12767
|
+
* Defines the screen size breakpoint (`lg`, `md`, `sm`, or `xs`) at which the dropdown switches to fullscreen mode on mobile.
|
|
12768
|
+
* When expanded, the dropdown will automatically display in fullscreen mode if the screen size is equal to or smaller than the selected breakpoint.
|
|
11764
12769
|
* @default sm
|
|
11765
12770
|
*/
|
|
11766
12771
|
fullscreenBreakpoint: {
|
|
@@ -11772,8 +12777,19 @@ class AuroCombobox extends LitElement {
|
|
|
11772
12777
|
* @private
|
|
11773
12778
|
*/
|
|
11774
12779
|
isDropdownFullscreen: {
|
|
11775
|
-
type: Boolean
|
|
11776
|
-
|
|
12780
|
+
type: Boolean,
|
|
12781
|
+
reflect: false
|
|
12782
|
+
},
|
|
12783
|
+
|
|
12784
|
+
/**
|
|
12785
|
+
* @private
|
|
12786
|
+
* specifies the currently active option
|
|
12787
|
+
*/
|
|
12788
|
+
optionActive: {
|
|
12789
|
+
type: Object,
|
|
12790
|
+
reflect: false,
|
|
12791
|
+
attribute: false
|
|
12792
|
+
},
|
|
11777
12793
|
};
|
|
11778
12794
|
}
|
|
11779
12795
|
|
|
@@ -11925,6 +12941,18 @@ class AuroCombobox extends LitElement {
|
|
|
11925
12941
|
* @returns {void}
|
|
11926
12942
|
*/
|
|
11927
12943
|
configureDropdown() {
|
|
12944
|
+
|
|
12945
|
+
// Listen for the ID to be added to the dropdown so we can capture it and use it for accessibility.
|
|
12946
|
+
this.dropdown.addEventListener('auroDropdown-idAdded', (event) => {
|
|
12947
|
+
this.dropdownId = event.detail.id;
|
|
12948
|
+
});
|
|
12949
|
+
|
|
12950
|
+
// Listen for the dropdown to be shown or hidden
|
|
12951
|
+
this.dropdown.addEventListener("auroDropdown-toggled", (ev) => {
|
|
12952
|
+
this.dropdownOpen = ev.detail.expanded;
|
|
12953
|
+
});
|
|
12954
|
+
|
|
12955
|
+
// this.dropdown.addEventListener('auroDropdown-show', () => {
|
|
11928
12956
|
this.menuWrapper = this.dropdown.querySelector('.menuWrapper');
|
|
11929
12957
|
this.menuWrapper.append(this.menu);
|
|
11930
12958
|
|
|
@@ -11938,7 +12966,6 @@ class AuroCombobox extends LitElement {
|
|
|
11938
12966
|
this.hideBib = this.hideBib.bind(this);
|
|
11939
12967
|
this.bibtemplate.addEventListener('close-click', this.hideBib);
|
|
11940
12968
|
|
|
11941
|
-
this.dropdown.setAttribute('role', 'combobox');
|
|
11942
12969
|
this.dropdown.addEventListener('auroDropdown-triggerClick', () => {
|
|
11943
12970
|
this.showBib();
|
|
11944
12971
|
});
|
|
@@ -11954,7 +12981,6 @@ class AuroCombobox extends LitElement {
|
|
|
11954
12981
|
this.isDropdownFullscreen = event.detail.strategy === 'fullscreen';
|
|
11955
12982
|
setTimeout(this.transportInput);
|
|
11956
12983
|
});
|
|
11957
|
-
|
|
11958
12984
|
}
|
|
11959
12985
|
|
|
11960
12986
|
/**
|
|
@@ -12448,6 +13474,10 @@ class AuroCombobox extends LitElement {
|
|
|
12448
13474
|
?noFlip="${this.noFlip}"
|
|
12449
13475
|
disableEventShow>
|
|
12450
13476
|
<${this.inputTag}
|
|
13477
|
+
.a11yRole="${"combobox"}"
|
|
13478
|
+
.a11yExpanded="${this.dropdownOpen}"
|
|
13479
|
+
.a11yControls="${this.dropdownId}"
|
|
13480
|
+
id="${this.id || 'auro-combobox-input'}"
|
|
12451
13481
|
slot="trigger"
|
|
12452
13482
|
bordered
|
|
12453
13483
|
?onDark="${this.onDark}"
|