@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
|
@@ -3,6 +3,414 @@ import { classMap } from 'lit/directives/class-map.js';
|
|
|
3
3
|
import { unsafeStatic, literal, html } from 'lit/static-html.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
|
|
6
|
+
class DateFormatter {
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description Parses a date string into its components.
|
|
12
|
+
* @param {string} dateStr - Date string to parse.
|
|
13
|
+
* @param {string} format - Date format to parse.
|
|
14
|
+
* @returns {Object<key["month" | "day" | "year"]: number>|undefined}
|
|
15
|
+
*/
|
|
16
|
+
this.parseDate = (dateStr, format = 'mm/dd/yyyy') => {
|
|
17
|
+
|
|
18
|
+
// Guard Clause: Date string is defined
|
|
19
|
+
if (!dateStr) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Assume the separator is a "/" a defined in our code base
|
|
24
|
+
const separator = '/';
|
|
25
|
+
|
|
26
|
+
// Get the parts of the date and format
|
|
27
|
+
const valueParts = dateStr.split(separator);
|
|
28
|
+
const formatParts = format.split(separator);
|
|
29
|
+
|
|
30
|
+
// Check if the value and format have the correct number of parts
|
|
31
|
+
if (valueParts.length !== formatParts.length) {
|
|
32
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Date string and format length do not match');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Holds the result to be returned
|
|
36
|
+
const result = formatParts.reduce((acc, part, index) => {
|
|
37
|
+
const value = valueParts[index];
|
|
38
|
+
|
|
39
|
+
if ((/m/iu).test(part)) {
|
|
40
|
+
acc.month = value;
|
|
41
|
+
} else if ((/d/iu).test(part)) {
|
|
42
|
+
acc.day = value;
|
|
43
|
+
} else if ((/y/iu).test(part)) {
|
|
44
|
+
acc.year = value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return acc;
|
|
48
|
+
}, {});
|
|
49
|
+
|
|
50
|
+
// If we found all the parts, return the result
|
|
51
|
+
if (result.month && result.year) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Throw an error to let the dev know we were unable to parse the date string
|
|
56
|
+
throw new Error('AuroDatepickerUtilities | parseDate: Unable to parse date string');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Convert a date object to string format.
|
|
61
|
+
* @param {Object} date - Date to convert to string.
|
|
62
|
+
* @returns {Object} Returns the date as a string.
|
|
63
|
+
*/
|
|
64
|
+
this.getDateAsString = (date) => date.toLocaleDateString(undefined, {
|
|
65
|
+
year: "numeric",
|
|
66
|
+
month: "2-digit",
|
|
67
|
+
day: "2-digit",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Converts a date string to a North American date format.
|
|
72
|
+
* @param {String} dateStr - Date to validate.
|
|
73
|
+
* @param {String} format - Date format to validate against.
|
|
74
|
+
* @returns {Boolean}
|
|
75
|
+
*/
|
|
76
|
+
this.toNorthAmericanFormat = (dateStr, format) => {
|
|
77
|
+
|
|
78
|
+
if (format === 'mm/dd/yyyy') {
|
|
79
|
+
return dateStr;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const parsedDate = this.parseDate(dateStr, format);
|
|
83
|
+
|
|
84
|
+
if (!parsedDate) {
|
|
85
|
+
throw new Error('AuroDatepickerUtilities | toNorthAmericanFormat: Unable to parse date string');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { month, day, year } = parsedDate;
|
|
89
|
+
|
|
90
|
+
const dateParts = [];
|
|
91
|
+
if (month) {
|
|
92
|
+
dateParts.push(month);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (day) {
|
|
96
|
+
dateParts.push(day);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (year) {
|
|
100
|
+
dateParts.push(year);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return dateParts.join('/');
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const dateFormatter = new DateFormatter();
|
|
108
|
+
|
|
109
|
+
// filepath: dateConstraints.mjs
|
|
110
|
+
const DATE_UTIL_CONSTRAINTS = {
|
|
111
|
+
maxDay: 31,
|
|
112
|
+
maxMonth: 12,
|
|
113
|
+
maxYear: 2400,
|
|
114
|
+
minDay: 1,
|
|
115
|
+
minMonth: 1,
|
|
116
|
+
minYear: 1900,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
class AuroDateUtilitiesBase {
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @description The maximum day value allowed by the various utilities in this class.
|
|
123
|
+
* @readonly
|
|
124
|
+
* @type {Number}
|
|
125
|
+
*/
|
|
126
|
+
get maxDay() {
|
|
127
|
+
return DATE_UTIL_CONSTRAINTS.maxDay;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @description The maximum month value allowed by the various utilities in this class.
|
|
132
|
+
* @readonly
|
|
133
|
+
* @type {Number}
|
|
134
|
+
*/
|
|
135
|
+
get maxMonth() {
|
|
136
|
+
return DATE_UTIL_CONSTRAINTS.maxMonth;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @description The maximum year value allowed by the various utilities in this class.
|
|
141
|
+
* @readonly
|
|
142
|
+
* @type {Number}
|
|
143
|
+
*/
|
|
144
|
+
get maxYear() {
|
|
145
|
+
return DATE_UTIL_CONSTRAINTS.maxYear;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @description The minimum day value allowed by the various utilities in this class.
|
|
150
|
+
* @readonly
|
|
151
|
+
* @type {Number}
|
|
152
|
+
*/
|
|
153
|
+
get minDay() {
|
|
154
|
+
return DATE_UTIL_CONSTRAINTS.minDay;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @description The minimum month value allowed by the various utilities in this class.
|
|
159
|
+
* @readonly
|
|
160
|
+
* @type {Number}
|
|
161
|
+
*/
|
|
162
|
+
get minMonth() {
|
|
163
|
+
return DATE_UTIL_CONSTRAINTS.minMonth;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @description The minimum year value allowed by the various utilities in this class.
|
|
168
|
+
* @readonly
|
|
169
|
+
* @type {Number}
|
|
170
|
+
*/
|
|
171
|
+
get minYear() {
|
|
172
|
+
return DATE_UTIL_CONSTRAINTS.minYear;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* eslint-disable no-magic-numbers */
|
|
177
|
+
|
|
178
|
+
class AuroDateUtilities extends AuroDateUtilitiesBase {
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns the current century.
|
|
182
|
+
* @returns {String} The current century.
|
|
183
|
+
*/
|
|
184
|
+
getCentury () {
|
|
185
|
+
return String(new Date().getFullYear()).slice(0, 2);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Returns a four digit year.
|
|
190
|
+
* @param {String} year - The year to convert to four digits.
|
|
191
|
+
* @returns {String} The four digit year.
|
|
192
|
+
*/
|
|
193
|
+
getFourDigitYear (year) {
|
|
194
|
+
|
|
195
|
+
const strYear = String(year).trim();
|
|
196
|
+
return strYear.length <= 2 ? this.getCentury() + strYear : strYear;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
constructor() {
|
|
200
|
+
|
|
201
|
+
super();
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Compares two dates to see if they match.
|
|
205
|
+
* @param {Object} date1 - First date to compare.
|
|
206
|
+
* @param {Object} date2 - Second date to compare.
|
|
207
|
+
* @returns {Boolean} Returns true if the dates match.
|
|
208
|
+
*/
|
|
209
|
+
this.datesMatch = (date1, date2) => new Date(date1).getTime() === new Date(date2).getTime();
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Returns true if value passed in is a valid date.
|
|
213
|
+
* @param {String} date - Date to validate.
|
|
214
|
+
* @param {String} format - Date format to validate against.
|
|
215
|
+
* @returns {Boolean}
|
|
216
|
+
*/
|
|
217
|
+
this.validDateStr = (date, format) => {
|
|
218
|
+
|
|
219
|
+
// The length we expect the date string to be
|
|
220
|
+
const dateStrLength = format.length;
|
|
221
|
+
|
|
222
|
+
// Guard Clause: Date and format are defined
|
|
223
|
+
if (typeof date === "undefined" || typeof format === "undefined") {
|
|
224
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date and format are required');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Guard Clause: Date should be of type string
|
|
228
|
+
if (typeof date !== "string") {
|
|
229
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Date must be a string');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Guard Clause: Format should be of type string
|
|
233
|
+
if (typeof format !== "string") {
|
|
234
|
+
throw new Error('AuroDatepickerUtilities | validateDateStr: Format must be a string');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Guard Clause: Length is what we expect it to be
|
|
238
|
+
if (date.length !== dateStrLength) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
// Get a formatted date string and parse it
|
|
242
|
+
const dateParts = dateFormatter.parseDate(date, format);
|
|
243
|
+
|
|
244
|
+
// Guard Clause: Date parse succeeded
|
|
245
|
+
if (!dateParts) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Create the expected date string based on the date parts
|
|
250
|
+
const expectedDateStr = `${dateParts.month}/${dateParts.day || "01"}/${this.getFourDigitYear(dateParts.year)}`;
|
|
251
|
+
|
|
252
|
+
// Generate a date object that we will extract a string date from to compare to the passed in date string
|
|
253
|
+
const dateObj = new Date(this.getFourDigitYear(dateParts.year), dateParts.month - 1, dateParts.day || 1);
|
|
254
|
+
|
|
255
|
+
// Get the date string of the date object we created from the string date
|
|
256
|
+
const actualDateStr = dateFormatter.getDateAsString(dateObj);
|
|
257
|
+
|
|
258
|
+
// Guard Clause: Generated date matches date string input
|
|
259
|
+
if (expectedDateStr !== actualDateStr) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// If we passed all other checks, we can assume the date is valid
|
|
264
|
+
return true;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Determines if a string date value matches the format provided.
|
|
269
|
+
* @param {string} value = The date string value.
|
|
270
|
+
* @param { string} format = The date format to match against.
|
|
271
|
+
* @returns {boolean}
|
|
272
|
+
*/
|
|
273
|
+
this.dateAndFormatMatch = (value, format) => {
|
|
274
|
+
|
|
275
|
+
// Ensure we have both values we need to do the comparison
|
|
276
|
+
if (!value || !format) {
|
|
277
|
+
throw new Error('AuroFormValidation | dateFormatMatch: value and format are required');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// If the lengths are different, they cannot match
|
|
281
|
+
if (value.length !== format.length) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Get the parts of the date
|
|
286
|
+
const dateParts = dateFormatter.parseDate(value, format);
|
|
287
|
+
|
|
288
|
+
// Validator for day
|
|
289
|
+
const dayValueIsValid = (day) => {
|
|
290
|
+
|
|
291
|
+
// Guard clause: if there is no day in the dateParts, we can ignore this check.
|
|
292
|
+
if (!dateParts.day) {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Guard clause: ensure day exists.
|
|
297
|
+
if (!day) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Convert day to number
|
|
302
|
+
const numDay = Number.parseInt(day, 10);
|
|
303
|
+
|
|
304
|
+
// Guard clause: ensure day is a valid integer
|
|
305
|
+
if (Number.isNaN(numDay)) {
|
|
306
|
+
throw new Error('AuroDatepickerUtilities | dayValueIsValid: Unable to parse day value integer');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Guard clause: ensure day is within the valid range
|
|
310
|
+
if (numDay < this.minDay || numDay > this.maxDay) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Default return
|
|
315
|
+
return true;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// Validator for month
|
|
319
|
+
const monthValueIsValid = (month) => {
|
|
320
|
+
|
|
321
|
+
// Guard clause: ensure month exists.
|
|
322
|
+
if (!month) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Convert month to number
|
|
327
|
+
const numMonth = Number.parseInt(month, 10);
|
|
328
|
+
|
|
329
|
+
// Guard clause: ensure month is a valid integer
|
|
330
|
+
if (Number.isNaN(numMonth)) {
|
|
331
|
+
throw new Error('AuroDatepickerUtilities | monthValueIsValid: Unable to parse month value integer');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Guard clause: ensure month is within the valid range
|
|
335
|
+
if (numMonth < this.minMonth || numMonth > this.maxMonth) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Default return
|
|
340
|
+
return true;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// Validator for year
|
|
344
|
+
const yearIsValid = (_year) => {
|
|
345
|
+
|
|
346
|
+
// Guard clause: ensure year exists.
|
|
347
|
+
if (!_year) {
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Get the full year
|
|
352
|
+
const year = this.getFourDigitYear(_year);
|
|
353
|
+
|
|
354
|
+
// Convert year to number
|
|
355
|
+
const numYear = Number.parseInt(year, 10);
|
|
356
|
+
|
|
357
|
+
// Guard clause: ensure year is a valid integer
|
|
358
|
+
if (Number.isNaN(numYear)) {
|
|
359
|
+
throw new Error('AuroDatepickerUtilities | yearValueIsValid: Unable to parse year value integer');
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Guard clause: ensure year is within the valid range
|
|
363
|
+
if (numYear < this.minYear || numYear > this.maxYear) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Default return
|
|
368
|
+
return true;
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// Self-contained checks for month, day, and year
|
|
372
|
+
const checks = [
|
|
373
|
+
monthValueIsValid(dateParts.month),
|
|
374
|
+
dayValueIsValid(dateParts.day),
|
|
375
|
+
yearIsValid(dateParts.year)
|
|
376
|
+
];
|
|
377
|
+
|
|
378
|
+
// If any of the checks failed, the date format does not match and the result is invalid
|
|
379
|
+
const isValid = checks.every((check) => check === true);
|
|
380
|
+
|
|
381
|
+
// If the check is invalid, return false
|
|
382
|
+
if (!isValid) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Default case
|
|
387
|
+
return true;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Export a class instance
|
|
393
|
+
const dateUtilities = new AuroDateUtilities();
|
|
394
|
+
|
|
395
|
+
// Export the class instance methods individually
|
|
396
|
+
const {
|
|
397
|
+
datesMatch,
|
|
398
|
+
validDateStr,
|
|
399
|
+
dateAndFormatMatch,
|
|
400
|
+
minDay,
|
|
401
|
+
minMonth,
|
|
402
|
+
minYear,
|
|
403
|
+
maxDay,
|
|
404
|
+
maxMonth,
|
|
405
|
+
maxYear
|
|
406
|
+
} = dateUtilities;
|
|
407
|
+
|
|
408
|
+
const {
|
|
409
|
+
toNorthAmericanFormat,
|
|
410
|
+
parseDate,
|
|
411
|
+
getDateAsString
|
|
412
|
+
} = dateFormatter;
|
|
413
|
+
|
|
6
414
|
// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
7
415
|
// See LICENSE in the project root for license information.
|
|
8
416
|
|
|
@@ -78,6 +486,7 @@ let AuroLibraryRuntimeUtils$3 = class AuroLibraryRuntimeUtils {
|
|
|
78
486
|
|
|
79
487
|
|
|
80
488
|
class AuroFormValidation {
|
|
489
|
+
|
|
81
490
|
constructor() {
|
|
82
491
|
this.runtimeUtils = new AuroLibraryRuntimeUtils$3();
|
|
83
492
|
}
|
|
@@ -169,17 +578,17 @@ class AuroFormValidation {
|
|
|
169
578
|
]
|
|
170
579
|
}
|
|
171
580
|
};
|
|
172
|
-
|
|
581
|
+
|
|
173
582
|
let elementType;
|
|
174
583
|
if (this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
175
584
|
elementType = 'input';
|
|
176
585
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-counter') || this.runtimeUtils.elementMatch(elem, 'auro-counter-group')) {
|
|
177
586
|
elementType = 'counter';
|
|
178
587
|
}
|
|
179
|
-
|
|
588
|
+
|
|
180
589
|
if (elementType) {
|
|
181
590
|
const rules = validationRules[elementType];
|
|
182
|
-
|
|
591
|
+
|
|
183
592
|
if (rules) {
|
|
184
593
|
Object.values(rules).flat().forEach(rule => {
|
|
185
594
|
if (rule.check(elem)) {
|
|
@@ -205,48 +614,82 @@ class AuroFormValidation {
|
|
|
205
614
|
if (!elem.value.match(emailRegex)) {
|
|
206
615
|
elem.validity = 'patternMismatch';
|
|
207
616
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
617
|
+
return;
|
|
208
618
|
}
|
|
209
619
|
} else if (elem.type === 'credit-card') {
|
|
210
620
|
if (elem.value.length > 0 && elem.value.length < elem.validationCCLength) {
|
|
211
621
|
elem.validity = 'tooShort';
|
|
212
622
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
623
|
+
return;
|
|
213
624
|
}
|
|
214
625
|
} else if (elem.type === 'number') {
|
|
215
626
|
if (elem.max !== undefined && Number(elem.max) < Number(elem.value)) {
|
|
216
627
|
elem.validity = 'rangeOverflow';
|
|
217
628
|
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
629
|
+
return;
|
|
218
630
|
}
|
|
219
631
|
|
|
220
632
|
if (elem.min !== undefined && elem.value?.length > 0 && Number(elem.min) > Number(elem.value)) {
|
|
221
633
|
elem.validity = 'rangeUnderflow';
|
|
222
634
|
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
635
|
+
return;
|
|
223
636
|
}
|
|
224
|
-
} else if (elem.type === 'date') {
|
|
225
|
-
|
|
637
|
+
} else if (elem.type === 'date' && elem.value?.length > 0) {
|
|
638
|
+
|
|
639
|
+
// Guard Clause: if the value is too short
|
|
640
|
+
if (elem.value.length < elem.lengthForType) {
|
|
641
|
+
|
|
226
642
|
elem.validity = 'tooShort';
|
|
227
643
|
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Guard Clause: If the value is too long for the type
|
|
648
|
+
if (elem.value?.length > elem.lengthForType) {
|
|
649
|
+
|
|
650
|
+
elem.validity = 'tooLong';
|
|
651
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// Validate that the date passed was the correct format
|
|
656
|
+
if (!dateAndFormatMatch(elem.value, elem.format)) {
|
|
657
|
+
elem.validity = 'patternMismatch';
|
|
658
|
+
elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || 'Invalid Date Format Entered';
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Validate that the date passed was a valid date
|
|
663
|
+
if (!validDateStr(elem.value, elem.format)) {
|
|
664
|
+
elem.validity = 'invalidDate';
|
|
665
|
+
elem.errorMessage = elem.setCustomValidityInvalidDate || elem.setCustomValidity || 'Invalid Date Entered';
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
231
668
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
669
|
+
// Perform the rest of the validation
|
|
670
|
+
const formattedValue = toNorthAmericanFormat(elem.value, elem.format);
|
|
671
|
+
const valueDate = new Date(formattedValue);
|
|
235
672
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
673
|
+
// // Validate max date
|
|
674
|
+
if (elem.max?.length === elem.lengthForType) {
|
|
675
|
+
|
|
676
|
+
const maxDate = new Date(toNorthAmericanFormat(elem.max, elem.format));
|
|
677
|
+
|
|
678
|
+
if (valueDate > maxDate) {
|
|
679
|
+
elem.validity = 'rangeOverflow';
|
|
680
|
+
elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
|
|
681
|
+
return;
|
|
240
682
|
}
|
|
683
|
+
}
|
|
241
684
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
685
|
+
// Validate min date
|
|
686
|
+
if (elem.min?.length === elem.lengthForType) {
|
|
687
|
+
const minDate = new Date(toNorthAmericanFormat(elem.min, elem.format));
|
|
245
688
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
689
|
+
if (valueDate < minDate) {
|
|
690
|
+
elem.validity = 'rangeUnderflow';
|
|
691
|
+
elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
|
|
692
|
+
return;
|
|
250
693
|
}
|
|
251
694
|
}
|
|
252
695
|
}
|
|
@@ -365,7 +808,7 @@ class AuroFormValidation {
|
|
|
365
808
|
if (input.validationMessage.length > 0) {
|
|
366
809
|
elem.errorMessage = input.validationMessage;
|
|
367
810
|
}
|
|
368
|
-
} else if (this.inputElements?.length > 0
|
|
811
|
+
} else if (this.inputElements?.length > 0 && elem.errorMessage === '') {
|
|
369
812
|
const firstInput = this.inputElements[0];
|
|
370
813
|
|
|
371
814
|
if (firstInput.validationMessage.length > 0) {
|
|
@@ -2267,7 +2710,7 @@ class AuroFloatingUI {
|
|
|
2267
2710
|
/**
|
|
2268
2711
|
* @private
|
|
2269
2712
|
* getting called on 'blur' in trigger or `focusin` in document
|
|
2270
|
-
*
|
|
2713
|
+
*
|
|
2271
2714
|
* Hides the bib if focus moves outside of the trigger or bib, unless a 'noHideOnThisFocusLoss' flag is set.
|
|
2272
2715
|
* This method checks if the currently active element is still within the trigger or bib.
|
|
2273
2716
|
* If not, and if the bib isn't in fullscreen mode with focus lost, it hides the bib.
|
|
@@ -2383,7 +2826,7 @@ class AuroFloatingUI {
|
|
|
2383
2826
|
// Close any other dropdown that is already open
|
|
2384
2827
|
const existedVisibleFloatingUI = document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
2385
2828
|
if (existedVisibleFloatingUI && existedVisibleFloatingUI !== this &&
|
|
2386
|
-
existedVisibleFloatingUI.isPopoverVisible &&
|
|
2829
|
+
existedVisibleFloatingUI.element.isPopoverVisible &&
|
|
2387
2830
|
document.expandedAuroFloater.eventPrefix === this.eventPrefix) {
|
|
2388
2831
|
document.expandedAuroFloater.hideBib();
|
|
2389
2832
|
}
|
|
@@ -2559,7 +3002,7 @@ class AuroFloatingUI {
|
|
|
2559
3002
|
this.id = window.crypto.randomUUID();
|
|
2560
3003
|
this.element.setAttribute('id', this.id);
|
|
2561
3004
|
}
|
|
2562
|
-
|
|
3005
|
+
|
|
2563
3006
|
this.element.bib.setAttribute("id", `${this.id}-floater-bib`);
|
|
2564
3007
|
}
|
|
2565
3008
|
|
|
@@ -2612,7 +3055,7 @@ class AuroFloatingUI {
|
|
|
2612
3055
|
if (this.element.bib) {
|
|
2613
3056
|
this.element.shadowRoot.append(this.element.bib);
|
|
2614
3057
|
}
|
|
2615
|
-
|
|
3058
|
+
|
|
2616
3059
|
// Remove event & keyboard listeners
|
|
2617
3060
|
if (this.element?.trigger) {
|
|
2618
3061
|
this.element.trigger.removeEventListener('keydown', this.handleEvent);
|
|
@@ -3002,7 +3445,6 @@ var tokensCss$1 = css`:host{--ds-auro-dropdown-label-text-color: var(--ds-basic-
|
|
|
3002
3445
|
|
|
3003
3446
|
const DESIGN_TOKEN_BREAKPOINT_PREFIX = '--ds-grid-breakpoint-';
|
|
3004
3447
|
const DESIGN_TOKEN_BREAKPOINT_OPTIONS = [
|
|
3005
|
-
'xl',
|
|
3006
3448
|
'lg',
|
|
3007
3449
|
'md',
|
|
3008
3450
|
'sm',
|
|
@@ -3074,7 +3516,6 @@ class AuroDropdownBib extends LitElement {
|
|
|
3074
3516
|
|
|
3075
3517
|
set mobileFullscreenBreakpoint(value) {
|
|
3076
3518
|
// verify the defined breakpoint is valid and exit out if not
|
|
3077
|
-
// 'disabled' is a design token breakpoint so it acts as our "undefined" value
|
|
3078
3519
|
const validatedValue = DESIGN_TOKEN_BREAKPOINT_OPTIONS.includes(value) ? value : undefined;
|
|
3079
3520
|
if (!validatedValue) {
|
|
3080
3521
|
this._mobileBreakpointValue = undefined;
|
|
@@ -3343,6 +3784,7 @@ var helpTextVersion = '1.0.0';
|
|
|
3343
3784
|
* @csspart helpText - The helpText content container.
|
|
3344
3785
|
* @event auroDropdown-triggerClick - Notifies that the trigger has been clicked.
|
|
3345
3786
|
* @event auroDropdown-toggled - Notifies that the visibility of the dropdown bib has changed.
|
|
3787
|
+
* @event auroDropdown-idAdded - Notifies consumers that the unique ID for the dropdown bib has been generated.
|
|
3346
3788
|
*/
|
|
3347
3789
|
class AuroDropdown extends LitElement {
|
|
3348
3790
|
constructor() {
|
|
@@ -3388,7 +3830,9 @@ class AuroDropdown extends LitElement {
|
|
|
3388
3830
|
this.rounded = false;
|
|
3389
3831
|
this.tabIndex = 0;
|
|
3390
3832
|
this.noToggle = false;
|
|
3833
|
+
this.a11yAutocomplete = 'none';
|
|
3391
3834
|
this.labeled = true;
|
|
3835
|
+
this.a11yRole = 'combobox';
|
|
3392
3836
|
this.onDark = false;
|
|
3393
3837
|
|
|
3394
3838
|
// floaterConfig
|
|
@@ -3524,6 +3968,16 @@ class AuroDropdown extends LitElement {
|
|
|
3524
3968
|
type: Number
|
|
3525
3969
|
},
|
|
3526
3970
|
|
|
3971
|
+
/**
|
|
3972
|
+
* The unique ID for the dropdown bib element.
|
|
3973
|
+
* @private
|
|
3974
|
+
*/
|
|
3975
|
+
dropdownId: {
|
|
3976
|
+
type: String,
|
|
3977
|
+
reflect: false,
|
|
3978
|
+
attribute: false
|
|
3979
|
+
},
|
|
3980
|
+
|
|
3527
3981
|
/**
|
|
3528
3982
|
* If declared in combination with `bordered` property or `helpText` slot content, will apply red color to both.
|
|
3529
3983
|
*/
|
|
@@ -3587,12 +4041,7 @@ class AuroDropdown extends LitElement {
|
|
|
3587
4041
|
},
|
|
3588
4042
|
|
|
3589
4043
|
/**
|
|
3590
|
-
* Defines the screen size breakpoint (`
|
|
3591
|
-
* at which the dropdown switches to fullscreen mode on mobile. `disabled` indicates a dropdown should _never_ enter fullscreen.
|
|
3592
|
-
*
|
|
3593
|
-
* When expanded, the dropdown will automatically display in fullscreen mode
|
|
3594
|
-
* if the screen size is equal to or smaller than the selected breakpoint.
|
|
3595
|
-
* @default sm
|
|
4044
|
+
* 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.
|
|
3596
4045
|
*/
|
|
3597
4046
|
fullscreenBreakpoint: {
|
|
3598
4047
|
type: String,
|
|
@@ -3691,6 +4140,23 @@ class AuroDropdown extends LitElement {
|
|
|
3691
4140
|
*/
|
|
3692
4141
|
tabIndex: {
|
|
3693
4142
|
type: Number
|
|
4143
|
+
},
|
|
4144
|
+
|
|
4145
|
+
/**
|
|
4146
|
+
* The value for the role attribute of the trigger element.
|
|
4147
|
+
*/
|
|
4148
|
+
a11yRole: {
|
|
4149
|
+
type: String || undefined,
|
|
4150
|
+
attribute: false,
|
|
4151
|
+
reflect: false
|
|
4152
|
+
},
|
|
4153
|
+
|
|
4154
|
+
/**
|
|
4155
|
+
* The value for the aria-autocomplete attribute of the trigger element.
|
|
4156
|
+
*/
|
|
4157
|
+
a11yAutocomplete: {
|
|
4158
|
+
type: String,
|
|
4159
|
+
attribute: false,
|
|
3694
4160
|
}
|
|
3695
4161
|
};
|
|
3696
4162
|
}
|
|
@@ -3715,15 +4181,6 @@ class AuroDropdown extends LitElement {
|
|
|
3715
4181
|
AuroLibraryRuntimeUtils$1$1.prototype.registerComponent(name, AuroDropdown);
|
|
3716
4182
|
}
|
|
3717
4183
|
|
|
3718
|
-
/**
|
|
3719
|
-
* Accessor for reusing the focusable entity query string.
|
|
3720
|
-
* @private
|
|
3721
|
-
* @returns {string}
|
|
3722
|
-
*/
|
|
3723
|
-
get focusableEntityQuery () {
|
|
3724
|
-
return 'auro-input, [auro-input], auro-button, [auro-button], button, input';
|
|
3725
|
-
}
|
|
3726
|
-
|
|
3727
4184
|
connectedCallback() {
|
|
3728
4185
|
super.connectedCallback();
|
|
3729
4186
|
}
|
|
@@ -3737,8 +4194,6 @@ class AuroDropdown extends LitElement {
|
|
|
3737
4194
|
updated(changedProperties) {
|
|
3738
4195
|
this.floater.handleUpdate(changedProperties);
|
|
3739
4196
|
|
|
3740
|
-
// Note: `disabled` is not a breakpoint (it is not a screen size),
|
|
3741
|
-
// so it looks like we never consume this - however, dropdownBib handles this in the setter as "undefined"
|
|
3742
4197
|
if (changedProperties.has('fullscreenBreakpoint')) {
|
|
3743
4198
|
this.bibContent.mobileFullscreenBreakpoint = this.fullscreenBreakpoint;
|
|
3744
4199
|
}
|
|
@@ -3752,7 +4207,22 @@ class AuroDropdown extends LitElement {
|
|
|
3752
4207
|
}
|
|
3753
4208
|
|
|
3754
4209
|
firstUpdated() {
|
|
4210
|
+
|
|
4211
|
+
// Configure the floater to, this will generate the ID for the bib
|
|
3755
4212
|
this.floater.configure(this, 'auroDropdown');
|
|
4213
|
+
|
|
4214
|
+
/**
|
|
4215
|
+
* @description Let subscribers know that the dropdown ID ha been generated and added.
|
|
4216
|
+
* @event auroDropdown-idAdded
|
|
4217
|
+
* @type {Object<key: 'id', value: string>} - The ID of the dropdown bib element.
|
|
4218
|
+
*/
|
|
4219
|
+
this.dispatchEvent(new CustomEvent('auroDropdown-idAdded', {detail: {id: this.floater.element.id}}));
|
|
4220
|
+
|
|
4221
|
+
// Set the bib ID locally if the user hasn't provided a focusable trigger
|
|
4222
|
+
if (!this.triggerContentFocusable) {
|
|
4223
|
+
this.dropdownId = this.floater.element.id;
|
|
4224
|
+
}
|
|
4225
|
+
|
|
3756
4226
|
this.bibContent = this.floater.element.bib;
|
|
3757
4227
|
|
|
3758
4228
|
// Add the tag name as an attribute if it is different than the component name
|
|
@@ -3874,7 +4344,7 @@ class AuroDropdown extends LitElement {
|
|
|
3874
4344
|
|
|
3875
4345
|
this.triggerContentSlot.forEach((node) => {
|
|
3876
4346
|
if (node.querySelectorAll) {
|
|
3877
|
-
const auroElements = node.querySelectorAll(
|
|
4347
|
+
const auroElements = node.querySelectorAll('auro-input, [auro-input], auro-button, [auro-button], button, input');
|
|
3878
4348
|
auroElements.forEach((auroEl) => {
|
|
3879
4349
|
auroEl.addEventListener('focus', this.bindFocusEventToTrigger);
|
|
3880
4350
|
auroEl.addEventListener('blur', this.bindFocusEventToTrigger);
|
|
@@ -3895,7 +4365,7 @@ class AuroDropdown extends LitElement {
|
|
|
3895
4365
|
|
|
3896
4366
|
this.triggerContentSlot.forEach((node) => {
|
|
3897
4367
|
if (node.querySelectorAll) {
|
|
3898
|
-
const auroElements = node.querySelectorAll(
|
|
4368
|
+
const auroElements = node.querySelectorAll('auro-input, [auro-input], auro-button, [auro-button], button, input');
|
|
3899
4369
|
auroElements.forEach((auroEl) => {
|
|
3900
4370
|
auroEl.removeEventListener('focus', this.bindFocusEventToTrigger);
|
|
3901
4371
|
auroEl.removeEventListener('blur', this.bindFocusEventToTrigger);
|
|
@@ -3904,6 +4374,30 @@ class AuroDropdown extends LitElement {
|
|
|
3904
4374
|
});
|
|
3905
4375
|
}
|
|
3906
4376
|
|
|
4377
|
+
/*
|
|
4378
|
+
* Sets aria attributes for the trigger element if a custom one is passed in.
|
|
4379
|
+
* @private
|
|
4380
|
+
* @method setTriggerAriaAttributes
|
|
4381
|
+
* @param { HTMLElement } triggerElement - The custom trigger element.
|
|
4382
|
+
*/
|
|
4383
|
+
clearTriggerA11yAttributes(triggerElement) {
|
|
4384
|
+
|
|
4385
|
+
if (!triggerElement || !triggerElement.removeAttribute) {
|
|
4386
|
+
return;
|
|
4387
|
+
}
|
|
4388
|
+
|
|
4389
|
+
// Reset appropriate attributes for a11y
|
|
4390
|
+
triggerElement.removeAttribute('aria-labelledby');
|
|
4391
|
+
if (triggerElement.getAttribute('id') === `${this.id}-trigger-element`) {
|
|
4392
|
+
triggerElement.removeAttribute('id');
|
|
4393
|
+
}
|
|
4394
|
+
triggerElement.removeAttribute('role');
|
|
4395
|
+
triggerElement.removeAttribute('aria-expanded');
|
|
4396
|
+
|
|
4397
|
+
triggerElement.removeAttribute('aria-controls');
|
|
4398
|
+
triggerElement.removeAttribute('aria-autocomplete');
|
|
4399
|
+
}
|
|
4400
|
+
|
|
3907
4401
|
/**
|
|
3908
4402
|
* Handles changes to the trigger content slot and updates related properties.
|
|
3909
4403
|
*
|
|
@@ -3917,32 +4411,41 @@ class AuroDropdown extends LitElement {
|
|
|
3917
4411
|
* @returns {void}
|
|
3918
4412
|
*/
|
|
3919
4413
|
handleTriggerContentSlotChange(event) {
|
|
4414
|
+
|
|
3920
4415
|
this.floater.handleTriggerTabIndex();
|
|
3921
4416
|
|
|
4417
|
+
// Get the trigger
|
|
4418
|
+
const trigger = this.shadowRoot.querySelector('#trigger');
|
|
4419
|
+
|
|
4420
|
+
// Get the trigger slot
|
|
3922
4421
|
const triggerSlot = this.shadowRoot.querySelector('.triggerContent slot');
|
|
3923
4422
|
|
|
4423
|
+
// If there's a trigger slot
|
|
3924
4424
|
if (triggerSlot) {
|
|
3925
4425
|
|
|
4426
|
+
// Get the content nodes to see if there are any children
|
|
3926
4427
|
const triggerContentNodes = triggerSlot.assignedNodes();
|
|
3927
4428
|
|
|
4429
|
+
// If there are children
|
|
3928
4430
|
if (triggerContentNodes) {
|
|
3929
4431
|
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
this.triggerContentFocusable = this.containsFocusableElement(node);
|
|
3933
|
-
}
|
|
3934
|
-
});
|
|
3935
|
-
}
|
|
3936
|
-
}
|
|
4432
|
+
// See if any of them are focusable elemeents
|
|
4433
|
+
this.triggerContentFocusable = triggerContentNodes.some((node) => this.containsFocusableElement(node));
|
|
3937
4434
|
|
|
3938
|
-
|
|
4435
|
+
// If any of them are focusable elements
|
|
4436
|
+
if (this.triggerContentFocusable) {
|
|
3939
4437
|
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
4438
|
+
// Assume the consumer will be providing their own a11y in whatever they passed in
|
|
4439
|
+
this.clearTriggerA11yAttributes(trigger);
|
|
4440
|
+
|
|
4441
|
+
// Remove the tabindex from the trigger so it doesn't interrupt focus flow
|
|
4442
|
+
trigger.removeAttribute('tabindex');
|
|
4443
|
+
} else {
|
|
4444
|
+
|
|
4445
|
+
// Add the tabindex to the trigger so that it's in the focus flow
|
|
4446
|
+
trigger.setAttribute('tabindex', '0');
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
3946
4449
|
}
|
|
3947
4450
|
|
|
3948
4451
|
if (event) {
|
|
@@ -3952,6 +4455,7 @@ class AuroDropdown extends LitElement {
|
|
|
3952
4455
|
|
|
3953
4456
|
if (this.triggerContentSlot) {
|
|
3954
4457
|
this.setupTriggerFocusEventBinding();
|
|
4458
|
+
|
|
3955
4459
|
this.hasTriggerContent = this.triggerContentSlot.some((slot) => {
|
|
3956
4460
|
if (slot.textContent.trim()) {
|
|
3957
4461
|
return true;
|
|
@@ -4019,10 +4523,13 @@ class AuroDropdown extends LitElement {
|
|
|
4019
4523
|
id="trigger"
|
|
4020
4524
|
class="trigger"
|
|
4021
4525
|
part="trigger"
|
|
4022
|
-
aria-labelledby="triggerLabel"
|
|
4023
4526
|
tabindex="${this.tabIndex}"
|
|
4024
4527
|
?showBorder="${this.showTriggerBorders}"
|
|
4025
|
-
|
|
4528
|
+
role="${ifDefined(this.triggerContentFocusable ? undefined : this.a11yRole)}"
|
|
4529
|
+
aria-expanded="${ifDefined(this.triggerContentFocusable ? undefined : this.isPopoverVisible)}"
|
|
4530
|
+
aria-controls="${ifDefined(this.triggerContentFocusable ? undefined : this.dropdownId)}"
|
|
4531
|
+
aria-labelledby="${ifDefined(this.triggerContentFocusable ? undefined : 'triggerLabel')}"
|
|
4532
|
+
>
|
|
4026
4533
|
<div class="triggerContentWrapper">
|
|
4027
4534
|
<label class="label" id="triggerLabel" hasTrigger=${this.hasTriggerContent}>
|
|
4028
4535
|
<slot name="label" @slotchange="${this.handleLabelSlotChange}"></slot>
|
|
@@ -4056,12 +4563,12 @@ class AuroDropdown extends LitElement {
|
|
|
4056
4563
|
<div id="bibSizer" part="size"></div>
|
|
4057
4564
|
<${this.dropdownBibTag}
|
|
4058
4565
|
id="bib"
|
|
4059
|
-
role="tooltip"
|
|
4060
4566
|
?data-show="${this.isPopoverVisible}"
|
|
4061
4567
|
?isfullscreen="${this.isBibFullscreen}"
|
|
4062
4568
|
?common="${this.common}"
|
|
4063
4569
|
?rounded="${this.common || this.rounded}"
|
|
4064
|
-
?inset="${this.common || this.inset}"
|
|
4570
|
+
?inset="${this.common || this.inset}"
|
|
4571
|
+
>
|
|
4065
4572
|
</${this.dropdownBibTag}>
|
|
4066
4573
|
</div>
|
|
4067
4574
|
`;
|
|
@@ -5082,11 +5589,8 @@ class AuroSelect extends LitElement {
|
|
|
5082
5589
|
},
|
|
5083
5590
|
|
|
5084
5591
|
/**
|
|
5085
|
-
* Defines the screen size breakpoint (`
|
|
5086
|
-
*
|
|
5087
|
-
*
|
|
5088
|
-
* When expanded, the dropdown will automatically display in fullscreen mode
|
|
5089
|
-
* if the screen size is equal to or smaller than the selected breakpoint.
|
|
5592
|
+
* Defines the screen size breakpoint (`lg`, `md`, `sm`, or `xs`) at which the dropdown switches to fullscreen mode on mobile.
|
|
5593
|
+
* When expanded, the dropdown will automatically display in fullscreen mode if the screen size is equal to or smaller than the selected breakpoint.
|
|
5090
5594
|
* @default sm
|
|
5091
5595
|
*/
|
|
5092
5596
|
fullscreenBreakpoint: {
|