@aurodesignsystem/auro-formkit 5.10.0 → 5.11.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 +55 -15
- package/components/bibtemplate/dist/auro-bibtemplate.d.ts +6 -0
- package/components/bibtemplate/dist/index.js +12 -0
- package/components/bibtemplate/dist/registered.js +12 -0
- package/components/checkbox/demo/api.min.js +3 -3
- package/components/checkbox/demo/index.min.js +3 -3
- package/components/checkbox/dist/index.js +3 -3
- package/components/checkbox/dist/registered.js +3 -3
- package/components/combobox/demo/api.min.js +1140 -305
- package/components/combobox/demo/index.min.js +1140 -305
- package/components/combobox/dist/auro-combobox.d.ts +24 -1
- package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +6 -0
- package/components/combobox/dist/index.js +1082 -264
- package/components/combobox/dist/registered.js +1082 -264
- package/components/counter/demo/api.min.js +583 -172
- package/components/counter/demo/index.min.js +583 -172
- package/components/counter/dist/auro-counter.d.ts +8 -0
- package/components/counter/dist/buttonVersion.d.ts +1 -1
- package/components/counter/dist/iconVersion.d.ts +1 -1
- package/components/counter/dist/index.js +583 -172
- package/components/counter/dist/registered.js +583 -172
- package/components/datepicker/demo/api.md +108 -85
- package/components/datepicker/demo/api.min.js +872 -257
- package/components/datepicker/demo/index.md +18 -12
- package/components/datepicker/demo/index.min.js +872 -257
- package/components/datepicker/dist/auro-calendar.d.ts +6 -0
- package/components/datepicker/dist/auro-datepicker.d.ts +11 -1
- package/components/datepicker/dist/index.js +819 -208
- package/components/datepicker/dist/registered.js +819 -208
- package/components/dropdown/demo/api.md +15 -17
- package/components/dropdown/demo/api.min.js +537 -183
- package/components/dropdown/demo/index.min.js +537 -183
- package/components/dropdown/dist/auro-dropdown.d.ts +27 -1
- package/components/dropdown/dist/auro-dropdownBib.d.ts +87 -0
- package/components/dropdown/dist/index.js +514 -160
- package/components/dropdown/dist/keyboardUtils.d.ts +18 -0
- package/components/dropdown/dist/registered.js +514 -160
- package/components/form/README.md +47 -2
- package/components/form/demo/api.js +2 -0
- package/components/form/demo/api.md +303 -30
- package/components/form/demo/api.min.js +69256 -62
- package/components/form/demo/index.html +0 -1
- package/components/form/demo/index.js +1 -0
- package/components/form/demo/index.md +1 -275
- package/components/form/demo/index.min.js +69255 -62
- package/components/form/demo/readme.md +47 -2
- package/components/form/demo/working.html +123 -32
- package/components/form/dist/auro-form.d.ts +98 -61
- package/components/form/dist/index.js +135 -51
- package/components/form/dist/registered.js +135 -51
- package/components/input/demo/api.md +1 -0
- package/components/input/demo/api.min.js +78 -24
- package/components/input/demo/index.min.js +78 -24
- package/components/input/dist/base-input.d.ts +34 -0
- package/components/input/dist/index.js +78 -24
- package/components/input/dist/registered.js +78 -24
- package/components/menu/demo/api.md +4 -10
- package/components/menu/demo/api.min.js +18 -5
- package/components/menu/demo/index.min.js +18 -5
- package/components/menu/dist/auro-menuoption.d.ts +0 -8
- package/components/menu/dist/iconVersion.d.ts +1 -1
- package/components/menu/dist/index.js +18 -5
- package/components/menu/dist/registered.js +18 -5
- package/components/radio/demo/api.min.js +3 -3
- package/components/radio/demo/index.min.js +3 -3
- package/components/radio/dist/index.js +3 -3
- package/components/radio/dist/registered.js +3 -3
- package/components/select/demo/api.js +2 -0
- package/components/select/demo/api.md +333 -78
- package/components/select/demo/api.min.js +945 -282
- package/components/select/demo/index.min.js +933 -282
- package/components/select/dist/auro-select.d.ts +26 -0
- package/components/select/dist/index.js +881 -247
- package/components/select/dist/registered.js +881 -247
- package/components/select/dist/selectKeyboardStrategy.d.ts +8 -0
- package/custom-elements.json +596 -89
- package/package.json +7 -5
|
@@ -106,26 +106,31 @@ class AuroLibraryRuntimeUtils {
|
|
|
106
106
|
*
|
|
107
107
|
* @slot default - The default slot for form elements.
|
|
108
108
|
*
|
|
109
|
-
* @event
|
|
109
|
+
* @event input - Fires when a child form element receives user input.
|
|
110
|
+
* @event change - Fires when a child form element's value changes or the form is initialized.
|
|
111
|
+
* @event reset - Fires when the form is reset. The event detail contains the previous value of the form before reset.
|
|
112
|
+
* @event submit - Fires when the form is submitted. The event detail contains the current value of the form.
|
|
110
113
|
*/
|
|
111
114
|
class AuroForm extends LitElement {
|
|
112
115
|
static get properties() {
|
|
113
116
|
return {
|
|
114
117
|
|
|
115
|
-
/**
|
|
116
|
-
* Applies designated CSS class to demo element - you want to delete me!
|
|
117
|
-
*/
|
|
118
|
-
cssClass: { type: Boolean },
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* If declared, use fixed pixel values for element shape.
|
|
122
|
-
*/
|
|
123
|
-
fixed: { type: Boolean, reflect: true },
|
|
118
|
+
/** @private */
|
|
124
119
|
formState: { type: Object, attribute: false },
|
|
120
|
+
|
|
121
|
+
/** @private */
|
|
125
122
|
_validity: { type: Object, attribute: false },
|
|
123
|
+
|
|
124
|
+
/** @private */
|
|
126
125
|
_isInitialState: { type: Boolean, attribute: false },
|
|
126
|
+
|
|
127
|
+
/** @private */
|
|
127
128
|
_elements: { type: Array, attribute: false },
|
|
129
|
+
|
|
130
|
+
/** @private */
|
|
128
131
|
_submitElements: { type: Array, attribute: false },
|
|
132
|
+
|
|
133
|
+
/** @private */
|
|
129
134
|
_resetElements: { type: Array, attribute: false },
|
|
130
135
|
};
|
|
131
136
|
}
|
|
@@ -133,20 +138,37 @@ class AuroForm extends LitElement {
|
|
|
133
138
|
constructor() {
|
|
134
139
|
super();
|
|
135
140
|
|
|
136
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* @type {FormState}
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
137
145
|
this.formState = {};
|
|
138
146
|
|
|
139
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* @type {"valid" | "invalid" | null}
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
140
151
|
this._validity = null;
|
|
152
|
+
|
|
153
|
+
/** @private */
|
|
141
154
|
this._isInitialState = true;
|
|
142
155
|
|
|
143
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* @type {(HTMLElement & {reset: () => void})[]}
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
144
160
|
this._elements = [];
|
|
145
161
|
|
|
146
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* @type {HTMLButtonElement[]}
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
147
166
|
this._submitelements = [];
|
|
148
167
|
|
|
149
|
-
/**
|
|
168
|
+
/**
|
|
169
|
+
* @type {HTMLButtonElement[]}
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
150
172
|
this._resetElements = [];
|
|
151
173
|
|
|
152
174
|
/**
|
|
@@ -156,11 +178,23 @@ class AuroForm extends LitElement {
|
|
|
156
178
|
this.mutationObservers = [];
|
|
157
179
|
|
|
158
180
|
// Bind listeners
|
|
181
|
+
/** @private */
|
|
159
182
|
this.reset = this.reset.bind(this);
|
|
183
|
+
|
|
184
|
+
/** @private */
|
|
160
185
|
this.submit = this.submit.bind(this);
|
|
186
|
+
|
|
187
|
+
/** @private */
|
|
161
188
|
this.sharedInputListener = this.sharedInputListener.bind(this);
|
|
189
|
+
|
|
190
|
+
/** @private */
|
|
162
191
|
this.sharedValidationListener = this.sharedValidationListener.bind(this);
|
|
192
|
+
|
|
193
|
+
/** @private */
|
|
163
194
|
this.mutationEventListener = this.mutationEventListener.bind(this);
|
|
195
|
+
|
|
196
|
+
/** @private */
|
|
197
|
+
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
164
198
|
}
|
|
165
199
|
|
|
166
200
|
// Note: button is NOT considered a form element in this context
|
|
@@ -205,6 +239,7 @@ class AuroForm extends LitElement {
|
|
|
205
239
|
* Check if the tag name is a form element.
|
|
206
240
|
* @param {HTMLElement} element - The element to check (attr or tag name).
|
|
207
241
|
* @returns {boolean}
|
|
242
|
+
* @private
|
|
208
243
|
*/
|
|
209
244
|
isFormElement(element) {
|
|
210
245
|
return this._isInElementCollection(AuroForm.formElementTags, element);
|
|
@@ -233,6 +268,7 @@ class AuroForm extends LitElement {
|
|
|
233
268
|
* Check if the tag name is a button element.
|
|
234
269
|
* @param {HTMLElement} element - The element to check.
|
|
235
270
|
* @returns {boolean}
|
|
271
|
+
* @private
|
|
236
272
|
*/
|
|
237
273
|
isButtonElement(element) {
|
|
238
274
|
return this._isInElementCollection(AuroForm.buttonElementTags, element);
|
|
@@ -243,13 +279,8 @@ class AuroForm extends LitElement {
|
|
|
243
279
|
}
|
|
244
280
|
|
|
245
281
|
/**
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* NOTE: form keys use `name` first, and `id` second if `name` is not available.
|
|
249
|
-
* This follows standard HTML5 form behavior - submission uses `name` by default when creating
|
|
250
|
-
* the FormData object.
|
|
251
|
-
*
|
|
252
|
-
* @returns {Record<string, string | number | boolean | string[] | null>} The form value.
|
|
282
|
+
* Returns the current values of all named form elements as a key-value object, keyed by each element's `name` attribute.
|
|
283
|
+
* @returns {Record<string, string | number | boolean | string[] | null>} The current form values.
|
|
253
284
|
*/
|
|
254
285
|
get value() {
|
|
255
286
|
return Object.keys(this.formState).reduce((acc, key) => {
|
|
@@ -261,6 +292,7 @@ class AuroForm extends LitElement {
|
|
|
261
292
|
/**
|
|
262
293
|
* Getter for internal _submitElements.
|
|
263
294
|
* @returns {HTMLButtonElement[]}
|
|
295
|
+
* @private
|
|
264
296
|
*/
|
|
265
297
|
get submitElements() {
|
|
266
298
|
return this._submitelements;
|
|
@@ -269,6 +301,7 @@ class AuroForm extends LitElement {
|
|
|
269
301
|
/**
|
|
270
302
|
* Returns a collection of elements that will reset the form.
|
|
271
303
|
* @returns {HTMLButtonElement[]}
|
|
304
|
+
* @private
|
|
272
305
|
*/
|
|
273
306
|
get resetElements() {
|
|
274
307
|
return this._resetElements;
|
|
@@ -295,8 +328,8 @@ class AuroForm extends LitElement {
|
|
|
295
328
|
}
|
|
296
329
|
|
|
297
330
|
/**
|
|
298
|
-
*
|
|
299
|
-
* @returns {"valid" | "invalid"}
|
|
331
|
+
* Returns `'valid'` if all required and interacted-with form elements are valid, `'invalid'` if any are not, or `null` if the form has not been interacted with yet.
|
|
332
|
+
* @returns {"valid" | "invalid" | null}
|
|
300
333
|
*/
|
|
301
334
|
get validity() {
|
|
302
335
|
// Force calculate, as sometimes validity won't reflect
|
|
@@ -305,6 +338,11 @@ class AuroForm extends LitElement {
|
|
|
305
338
|
return this._validity;
|
|
306
339
|
}
|
|
307
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Determines whether the form is in its initial (untouched) state and updates `_isInitialState` accordingly.
|
|
343
|
+
* @returns {void}
|
|
344
|
+
* @private
|
|
345
|
+
*/
|
|
308
346
|
_setInitialState() {
|
|
309
347
|
const anyTainted = Object.keys(this.formState).some((key) => this.formState[key].validity !== null || this.formState[key].value !== null);
|
|
310
348
|
|
|
@@ -318,13 +356,18 @@ class AuroForm extends LitElement {
|
|
|
318
356
|
}
|
|
319
357
|
|
|
320
358
|
/**
|
|
321
|
-
*
|
|
359
|
+
* Returns `true` if no form element has been interacted with or had its value changed since the form was initialized or last reset.
|
|
322
360
|
* @returns {boolean}
|
|
323
361
|
*/
|
|
324
362
|
get isInitialState() {
|
|
325
363
|
return this._isInitialState;
|
|
326
364
|
}
|
|
327
365
|
|
|
366
|
+
/**
|
|
367
|
+
* Enables or disables submit and reset buttons based on the current form state and validity.
|
|
368
|
+
* @returns {void}
|
|
369
|
+
* @private
|
|
370
|
+
*/
|
|
328
371
|
setDisabledStateOnButtons() {
|
|
329
372
|
this._resetElements.forEach((element) => {
|
|
330
373
|
if (this.isInitialState) {
|
|
@@ -346,6 +389,7 @@ class AuroForm extends LitElement {
|
|
|
346
389
|
/**
|
|
347
390
|
* Construct the query strings from elements, append them together, execute, and return the NodeList.
|
|
348
391
|
* @returns {NodeList}
|
|
392
|
+
* @private
|
|
349
393
|
*/
|
|
350
394
|
queryAuroElements() {
|
|
351
395
|
const queries = [
|
|
@@ -392,6 +436,8 @@ class AuroForm extends LitElement {
|
|
|
392
436
|
|
|
393
437
|
/**
|
|
394
438
|
* Initialize (or reinitialize) the form state.
|
|
439
|
+
* @returns {void}
|
|
440
|
+
* @private
|
|
395
441
|
*/
|
|
396
442
|
initializeState() {
|
|
397
443
|
this.formState = {};
|
|
@@ -432,7 +478,8 @@ class AuroForm extends LitElement {
|
|
|
432
478
|
}
|
|
433
479
|
|
|
434
480
|
/**
|
|
435
|
-
*
|
|
481
|
+
* Resets all form elements to their initial state and fires a `reset` event. The event's `detail.previousValue` contains the form values captured immediately before the reset.
|
|
482
|
+
* @returns {void}
|
|
436
483
|
*/
|
|
437
484
|
reset() {
|
|
438
485
|
const previousValue = this.value;
|
|
@@ -460,36 +507,36 @@ class AuroForm extends LitElement {
|
|
|
460
507
|
}
|
|
461
508
|
|
|
462
509
|
/**
|
|
463
|
-
*
|
|
510
|
+
* Validates all form elements. If all are valid, fires a `submit` event with `detail.value` containing the current form values. If any element is invalid, its error state is surfaced and the `submit` event is not fired.
|
|
511
|
+
* @returns {Promise<void>}
|
|
464
512
|
*/
|
|
465
|
-
submit() {
|
|
466
|
-
//
|
|
467
|
-
// 1. Submit triggers a forced validation on ALL elements
|
|
468
|
-
// 2. Wait for validation to complete (this.updateComplete.then or similar)
|
|
469
|
-
// 3. If still valid, go ahead with submit.
|
|
513
|
+
async submit() {
|
|
514
|
+
// Force validation on ALL elements
|
|
470
515
|
this._elements.forEach((element) => {
|
|
471
|
-
|
|
472
|
-
// Next line currently does NOT force
|
|
473
|
-
element.validate();
|
|
474
|
-
}
|
|
516
|
+
element.validate(true);
|
|
475
517
|
});
|
|
476
518
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
519
|
+
// Wait for validation to complete and formState to update
|
|
520
|
+
await this.updateComplete;
|
|
521
|
+
|
|
522
|
+
// Only dispatch submit event if form is valid
|
|
523
|
+
if (this.validity === 'valid') {
|
|
524
|
+
this.dispatchEvent(new CustomEvent('submit', {
|
|
525
|
+
bubbles: true,
|
|
526
|
+
composed: true,
|
|
527
|
+
detail: {
|
|
528
|
+
value: this.value
|
|
529
|
+
}
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
484
532
|
}
|
|
485
533
|
|
|
486
534
|
/**
|
|
487
|
-
*
|
|
488
|
-
* @param {string} [name="auro-form"] - The
|
|
535
|
+
* Registers the `auro-form` custom element with the browser under a given tag name.
|
|
536
|
+
* @param {string} [name="auro-form"] - The custom element tag name to register.
|
|
489
537
|
*
|
|
490
538
|
* @example
|
|
491
|
-
* AuroForm.register("custom-form") //
|
|
492
|
-
*
|
|
539
|
+
* AuroForm.register("custom-form") // registers as <custom-form>
|
|
493
540
|
*/
|
|
494
541
|
static register(name = "auro-form") {
|
|
495
542
|
AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroForm);
|
|
@@ -497,8 +544,8 @@ class AuroForm extends LitElement {
|
|
|
497
544
|
|
|
498
545
|
/**
|
|
499
546
|
* Shared input listener for all form elements.
|
|
500
|
-
* @private
|
|
501
547
|
* @param {Event} event - The event that is fired from the form element.
|
|
548
|
+
* @private
|
|
502
549
|
*/
|
|
503
550
|
sharedInputListener(event) {
|
|
504
551
|
const targetName = event.target.getAttribute("name");
|
|
@@ -530,8 +577,8 @@ class AuroForm extends LitElement {
|
|
|
530
577
|
|
|
531
578
|
/**
|
|
532
579
|
* Shared validation listener for all form elements.
|
|
533
|
-
* @private
|
|
534
580
|
* @param {Event} event - The event that is fired from the form element.
|
|
581
|
+
* @private
|
|
535
582
|
*/
|
|
536
583
|
sharedValidationListener(event) {
|
|
537
584
|
const targetName = event.target.getAttribute("name");
|
|
@@ -548,24 +595,58 @@ class AuroForm extends LitElement {
|
|
|
548
595
|
this.requestUpdate('formState');
|
|
549
596
|
}
|
|
550
597
|
|
|
598
|
+
/**
|
|
599
|
+
* Handle Enter key press on form elements.
|
|
600
|
+
* @param {KeyboardEvent} event - The keyboard event.
|
|
601
|
+
* @private
|
|
602
|
+
*/
|
|
603
|
+
handleKeyDown(event) {
|
|
604
|
+
if (event.key === 'Enter' && this.isFormElement(event.target)) {
|
|
605
|
+
// Don't submit if it's a textarea (allow new lines)
|
|
606
|
+
if (event.target.tagName.toLowerCase() === 'textarea' ||
|
|
607
|
+
event.target.hasAttribute('textarea')) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
event.preventDefault();
|
|
612
|
+
this.submit();
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Attaches input, validation, and keydown listeners to all tracked form and button elements.
|
|
618
|
+
* Removes existing listeners first to avoid duplicates on re-initialization.
|
|
619
|
+
* @returns {void}
|
|
620
|
+
* @private
|
|
621
|
+
*/
|
|
551
622
|
_attachEventListeners() {
|
|
552
623
|
this.queryAuroElements().forEach((element) => {
|
|
553
624
|
// remove any existing event listeners (in case of re-initialization)
|
|
554
625
|
element.removeEventListener('input', this.sharedInputListener);
|
|
555
626
|
element.removeEventListener('auroFormElement-validated', this.sharedValidationListener);
|
|
627
|
+
element.removeEventListener('keydown', this.handleKeyDown);
|
|
556
628
|
|
|
557
629
|
// add new event listeners
|
|
558
630
|
element.addEventListener('input', this.sharedInputListener);
|
|
559
631
|
element.addEventListener('auroFormElement-validated', this.sharedValidationListener);
|
|
632
|
+
element.addEventListener('keydown', this.handleKeyDown);
|
|
560
633
|
});
|
|
561
634
|
}
|
|
562
635
|
|
|
636
|
+
/**
|
|
637
|
+
* @param {import('lit').PropertyValues} _changedProperties - Map of changed properties with their previous values.
|
|
638
|
+
* @returns {void}
|
|
639
|
+
*/
|
|
563
640
|
firstUpdated(_changedProperties) {
|
|
564
641
|
super.firstUpdated(_changedProperties);
|
|
565
642
|
|
|
566
643
|
this._attachEventListeners();
|
|
567
644
|
}
|
|
568
645
|
|
|
646
|
+
/**
|
|
647
|
+
* @param {import('lit').PropertyValues} _changedProperties - Map of changed properties with their previous values.
|
|
648
|
+
* @returns {void}
|
|
649
|
+
*/
|
|
569
650
|
updated(_changedProperties) {
|
|
570
651
|
super.updated(_changedProperties);
|
|
571
652
|
|
|
@@ -586,8 +667,8 @@ class AuroForm extends LitElement {
|
|
|
586
667
|
* root-level elements are added/removed. This is a workaround to ensure
|
|
587
668
|
* nested form elements are also observed.
|
|
588
669
|
*
|
|
589
|
-
* @private
|
|
590
670
|
* @returns {void}
|
|
671
|
+
* @private
|
|
591
672
|
*/
|
|
592
673
|
mutationEventListener() {
|
|
593
674
|
this.initializeState();
|
|
@@ -598,6 +679,7 @@ class AuroForm extends LitElement {
|
|
|
598
679
|
* Slot change event listener. This is the main entry point for the form element.
|
|
599
680
|
* @param {Event} event - The slot change event.
|
|
600
681
|
* @returns {void}
|
|
682
|
+
* @private
|
|
601
683
|
*/
|
|
602
684
|
onSlotChange(event) {
|
|
603
685
|
this.initializeState();
|
|
@@ -621,7 +703,9 @@ class AuroForm extends LitElement {
|
|
|
621
703
|
});
|
|
622
704
|
}
|
|
623
705
|
|
|
624
|
-
|
|
706
|
+
/**
|
|
707
|
+
* @returns {import('lit').TemplateResult}
|
|
708
|
+
*/
|
|
625
709
|
render() {
|
|
626
710
|
return html`
|
|
627
711
|
<form>
|
|
@@ -9,6 +9,7 @@ The `auro-input` element provides users a way to enter data into a text field.
|
|
|
9
9
|
|
|
10
10
|
| Property | Attribute | Type | Default | Description |
|
|
11
11
|
|-----------------------------------|-----------------------------------|--------------------------------------------------|-------------|--------------------------------------------------|
|
|
12
|
+
| `a11yActivedescendant` | `a11yActivedescendant` | `string` | | The value for the aria-activedescendant attribute.<br />Points to the ID of the currently active/highlighted option in a listbox. |
|
|
12
13
|
| `a11yControls` | `a11yControls` | `string` | | The value for the aria-controls attribute. |
|
|
13
14
|
| `a11yExpanded` | `a11yExpanded` | `boolean` | | The value for the aria-expanded attribute. |
|
|
14
15
|
| `a11yRole` | `a11yRole` | `string` | | The value for the role attribute. |
|
|
@@ -4964,7 +4964,7 @@ class AuroFormValidation {
|
|
|
4964
4964
|
}
|
|
4965
4965
|
}
|
|
4966
4966
|
|
|
4967
|
-
if (!hasValue && elem.required && elem.touched) {
|
|
4967
|
+
if (!hasValue && elem.required && (force || elem.touched)) {
|
|
4968
4968
|
elem.validity = 'valueMissing';
|
|
4969
4969
|
elem.errorMessage = elem.setCustomValidityValueMissing || elem.setCustomValidity || '';
|
|
4970
4970
|
} else if (hasValue && this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
@@ -4988,7 +4988,7 @@ class AuroFormValidation {
|
|
|
4988
4988
|
if (!isCombobox || isCombobox && !elem.persistInput) {
|
|
4989
4989
|
|
|
4990
4990
|
// run validation on all inputs since we're going to use them to set the validity of this component
|
|
4991
|
-
this.auroInputElements.forEach(input => input.validate());
|
|
4991
|
+
this.auroInputElements.forEach(input => input.validate(force));
|
|
4992
4992
|
|
|
4993
4993
|
// Reset element validity to the validity of the input
|
|
4994
4994
|
elem.validity = this.auroInputElements[0].validity;
|
|
@@ -5194,6 +5194,17 @@ class AuroElement extends i$3 {
|
|
|
5194
5194
|
*/
|
|
5195
5195
|
class BaseInput extends AuroElement {
|
|
5196
5196
|
|
|
5197
|
+
// Delegate focus to the native <input> inside the shadow root so that
|
|
5198
|
+
// showModal()'s dialog focusing steps reach the input element.
|
|
5199
|
+
// This keeps the mobile virtual keyboard open when the fullscreen dialog
|
|
5200
|
+
// opens, because the browser sees an input-to-input focus transfer.
|
|
5201
|
+
static get shadowRootOptions() {
|
|
5202
|
+
return {
|
|
5203
|
+
...AuroElement.shadowRootOptions,
|
|
5204
|
+
delegatesFocus: true,
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
|
|
5197
5208
|
constructor() {
|
|
5198
5209
|
super();
|
|
5199
5210
|
|
|
@@ -5211,6 +5222,7 @@ class BaseInput extends AuroElement {
|
|
|
5211
5222
|
this.icon = false;
|
|
5212
5223
|
this.disabled = false;
|
|
5213
5224
|
this.dvInputOnly = false;
|
|
5225
|
+
this.hideLabelVisually = false;
|
|
5214
5226
|
this.max = undefined;
|
|
5215
5227
|
this.maxLength = undefined;
|
|
5216
5228
|
this.min = undefined;
|
|
@@ -5318,6 +5330,15 @@ class BaseInput extends AuroElement {
|
|
|
5318
5330
|
reflect: true
|
|
5319
5331
|
},
|
|
5320
5332
|
|
|
5333
|
+
/**
|
|
5334
|
+
* The value for the aria-activedescendant attribute.
|
|
5335
|
+
* Points to the ID of the currently active/highlighted option in a listbox.
|
|
5336
|
+
*/
|
|
5337
|
+
a11yActivedescendant: {
|
|
5338
|
+
type: String,
|
|
5339
|
+
reflect: true
|
|
5340
|
+
},
|
|
5341
|
+
|
|
5321
5342
|
/**
|
|
5322
5343
|
* If set, the label will remain fixed in the active position.
|
|
5323
5344
|
*/
|
|
@@ -5424,6 +5445,16 @@ class BaseInput extends AuroElement {
|
|
|
5424
5445
|
attribute: false
|
|
5425
5446
|
},
|
|
5426
5447
|
|
|
5448
|
+
/**
|
|
5449
|
+
* If set, the label will be hidden visually but still accessible to assistive technologies.
|
|
5450
|
+
* @private
|
|
5451
|
+
*/
|
|
5452
|
+
hideLabelVisually: {
|
|
5453
|
+
type: Boolean,
|
|
5454
|
+
reflect: true
|
|
5455
|
+
},
|
|
5456
|
+
|
|
5457
|
+
|
|
5427
5458
|
/**
|
|
5428
5459
|
* If set, will render an icon inside the input to the left of the value. Support is limited to auro-input instances with credit card format.
|
|
5429
5460
|
*/
|
|
@@ -6001,31 +6032,34 @@ class BaseInput extends AuroElement {
|
|
|
6001
6032
|
// Process credit card type detection and formatting during input
|
|
6002
6033
|
if (this.type === 'credit-card') {
|
|
6003
6034
|
this.processCreditCard();
|
|
6004
|
-
|
|
6035
|
+
this.touched = true;
|
|
6036
|
+
this.validation.validate(this);
|
|
6037
|
+
} else {
|
|
6005
6038
|
|
|
6006
|
-
|
|
6007
|
-
|
|
6039
|
+
// Sets value property to value of element value (el.value).
|
|
6040
|
+
this.value = this.inputElement.value;
|
|
6008
6041
|
|
|
6009
|
-
|
|
6010
|
-
|
|
6042
|
+
// Determine if the value change was programmatic, including autofill.
|
|
6043
|
+
const inputWasProgrammatic = !this.matches(":focus") || event.isProgrammatic;
|
|
6011
6044
|
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6045
|
+
// Validation on input or programmatic value change (including autofill).
|
|
6046
|
+
if (this.validateOnInput || inputWasProgrammatic) {
|
|
6047
|
+
this.touched = true;
|
|
6048
|
+
this.validation.validate(this);
|
|
6049
|
+
}
|
|
6017
6050
|
|
|
6018
|
-
|
|
6019
|
-
|
|
6051
|
+
// Prevents cursor jumping in Safari.
|
|
6052
|
+
const { selectionStart } = this.inputElement;
|
|
6020
6053
|
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6054
|
+
if (this.setSelectionInputTypes.includes(this.type)) {
|
|
6055
|
+
this.updateComplete.then(() => {
|
|
6056
|
+
try {
|
|
6057
|
+
this.inputElement.setSelectionRange(selectionStart, selectionStart);
|
|
6058
|
+
} catch (error) { // eslint-disable-line
|
|
6059
|
+
// do nothing
|
|
6060
|
+
}
|
|
6061
|
+
});
|
|
6062
|
+
}
|
|
6029
6063
|
}
|
|
6030
6064
|
}
|
|
6031
6065
|
|
|
@@ -6058,6 +6092,11 @@ class BaseInput extends AuroElement {
|
|
|
6058
6092
|
this.inputElement.scrollLeft = 100;
|
|
6059
6093
|
|
|
6060
6094
|
if (!this.noValidate) {
|
|
6095
|
+
// For credit card inputs with mask, ensure value is synced from mask instance
|
|
6096
|
+
if (this.type === 'credit-card' && this.maskInstance) {
|
|
6097
|
+
this.value = this.maskInstance.value;
|
|
6098
|
+
}
|
|
6099
|
+
|
|
6061
6100
|
this.validation.validate(this);
|
|
6062
6101
|
}
|
|
6063
6102
|
}
|
|
@@ -6082,6 +6121,20 @@ class BaseInput extends AuroElement {
|
|
|
6082
6121
|
return activeEl;
|
|
6083
6122
|
}
|
|
6084
6123
|
|
|
6124
|
+
/**
|
|
6125
|
+
* Sets the active descendant element for accessibility.
|
|
6126
|
+
* Uses ariaActiveDescendantElement to cross shadow DOM boundaries.
|
|
6127
|
+
* This function is used in components that contain `auro-input` to set the active descendant.
|
|
6128
|
+
* @private
|
|
6129
|
+
* @param {HTMLElement|null} element - The element to set as the active descendant, or null to clear.
|
|
6130
|
+
* @returns {void}
|
|
6131
|
+
*/
|
|
6132
|
+
setActiveDescendant(element) {
|
|
6133
|
+
if (this.inputElement) {
|
|
6134
|
+
this.inputElement.ariaActiveDescendantElement = element;
|
|
6135
|
+
}
|
|
6136
|
+
}
|
|
6137
|
+
|
|
6085
6138
|
/**
|
|
6086
6139
|
* Validates value.
|
|
6087
6140
|
* @param {boolean} [force=false] - Whether to force validation.
|
|
@@ -6706,7 +6759,7 @@ class AuroHelpText extends i$3 {
|
|
|
6706
6759
|
}
|
|
6707
6760
|
}
|
|
6708
6761
|
|
|
6709
|
-
var formkitVersion = '
|
|
6762
|
+
var formkitVersion = '202603102257';
|
|
6710
6763
|
|
|
6711
6764
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
6712
6765
|
// See LICENSE in the project root for license information.
|
|
@@ -6888,7 +6941,7 @@ class AuroInput extends BaseInput {
|
|
|
6888
6941
|
return {
|
|
6889
6942
|
'is-disabled': this.disabled,
|
|
6890
6943
|
'withValue': this.hasValue,
|
|
6891
|
-
'util_displayHiddenVisually': this.labelHidden,
|
|
6944
|
+
'util_displayHiddenVisually': this.labelHidden || this.hideLabelVisually,
|
|
6892
6945
|
[this.labelFontClass]: true,
|
|
6893
6946
|
};
|
|
6894
6947
|
}
|
|
@@ -7060,6 +7113,7 @@ class AuroInput extends BaseInput {
|
|
|
7060
7113
|
?activeLabel="${this.activeLabel}"
|
|
7061
7114
|
?disabled="${this.disabled}"
|
|
7062
7115
|
?required="${this.required}"
|
|
7116
|
+
aria-activedescendant=${o(this.a11yActivedescendant)}
|
|
7063
7117
|
aria-controls=${o(this.a11yControls)}
|
|
7064
7118
|
aria-describedby="${this.uniqueId}"
|
|
7065
7119
|
aria-expanded=${o(this.a11yExpanded)}
|