@aurodesignsystem-dev/auro-formkit 0.0.0-pr1460.2 → 0.0.0-pr1464.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.
Files changed (85) hide show
  1. package/components/checkbox/demo/api.html +4 -26
  2. package/components/checkbox/demo/getting-started.md +5 -6
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/api.html +4 -25
  7. package/components/combobox/demo/getting-started.md +76 -27
  8. package/components/combobox/demo/index.min.js +15 -1
  9. package/components/combobox/demo/registered.min.js +1517 -1509
  10. package/components/combobox/dist/auro-combobox.d.ts +1 -1
  11. package/components/combobox/dist/index.js +18 -11
  12. package/components/combobox/dist/registered.js +18 -11
  13. package/components/counter/demo/api.html +5 -29
  14. package/components/counter/demo/getting-started.md +4 -3
  15. package/components/counter/demo/index.min.js +8392 -1
  16. package/components/counter/dist/index.js +53 -5284
  17. package/components/counter/dist/registered.js +106 -5110
  18. package/components/datepicker/demo/accessibility.html +0 -1
  19. package/components/datepicker/demo/api.html +4 -29
  20. package/components/datepicker/demo/getting-started.md +25 -2
  21. package/components/datepicker/demo/index.min.js +24612 -1
  22. package/components/datepicker/demo/readme.html +2 -10
  23. package/components/datepicker/dist/index.js +10 -10
  24. package/components/datepicker/dist/registered.js +10 -10
  25. package/components/dropdown/demo/api.html +5 -31
  26. package/components/dropdown/demo/getting-started.md +34 -2
  27. package/components/dropdown/demo/index.min.js +5097 -1
  28. package/components/dropdown/dist/index.js +1 -1
  29. package/components/dropdown/dist/registered.js +1 -1
  30. package/components/form/demo/api.html +5 -27
  31. package/components/form/demo/getting-started.md +5 -6
  32. package/components/form/demo/index.min.js +719 -2
  33. package/components/form/demo/keyboard-behavior.md +38 -0
  34. package/components/form/demo/pages.json +1 -1
  35. package/components/form/demo/registerDemoDeps.min.js +11842 -60908
  36. package/components/input/demo/accessibility.md +1 -1
  37. package/components/input/demo/api.html +15 -26
  38. package/components/input/demo/auro-input.min.js +1 -1
  39. package/components/input/demo/getting-started.md +1 -1
  40. package/components/input/demo/readme.html +2 -10
  41. package/components/input/dist/index.js +1 -1
  42. package/components/input/dist/registered.js +1 -1
  43. package/components/menu/demo/api.html +5 -30
  44. package/components/menu/demo/api.md +1 -1
  45. package/components/menu/demo/getting-started.md +1 -1
  46. package/components/menu/demo/index.min.js +1574 -1573
  47. package/components/menu/dist/auro-menu.context.d.ts +0 -1
  48. package/components/menu/dist/auro-menu.d.ts +1 -1
  49. package/components/menu/dist/index.js +1609 -1608
  50. package/components/menu/dist/registered.js +1553 -1552
  51. package/components/radio/demo/api.html +7 -28
  52. package/components/radio/demo/getting-started.md +27 -2
  53. package/components/radio/demo/index.md +1 -3
  54. package/components/radio/demo/index.min.js +1 -1
  55. package/components/radio/demo/readme.md +0 -2
  56. package/components/radio/dist/index.js +1 -1
  57. package/components/radio/dist/registered.js +1 -1
  58. package/components/select/demo/api.html +5 -42
  59. package/components/select/demo/getting-started.md +39 -5
  60. package/components/select/demo/registered.min.js +1503 -1502
  61. package/components/select/dist/index.js +2 -2
  62. package/components/select/dist/registered.js +2 -2
  63. package/custom-elements.json +1487 -1489
  64. package/package.json +37 -4
  65. package/components/combobox/demo/api.js +0 -39
  66. package/components/combobox/demo/api.min.js +0 -106
  67. package/components/combobox/demo/install.html +0 -50
  68. package/components/combobox/demo/styles.css +0 -974
  69. package/components/combobox/demo/swap-value.min.js +0 -16
  70. package/components/counter/demo/api.js +0 -24
  71. package/components/counter/demo/api.min.js +0 -52
  72. package/components/counter/demo/auro-counter-group.min.js +0 -8394
  73. package/components/datepicker/demo/api.js +0 -37
  74. package/components/datepicker/demo/api.min.js +0 -300
  75. package/components/datepicker/demo/auro-datepicker.min.js +0 -24614
  76. package/components/dropdown/demo/api.js +0 -26
  77. package/components/dropdown/demo/api.min.js +0 -109
  78. package/components/dropdown/demo/auro-dropdown.min.js +0 -5099
  79. package/components/form/demo/api.js +0 -5
  80. package/components/form/demo/api.min.js +0 -5
  81. package/components/form/demo/auro-form.min.js +0 -718
  82. package/components/form/demo/autocomplete.html +0 -31
  83. package/components/radio/demo/api.js +0 -19
  84. package/components/radio/demo/api.min.js +0 -44
  85. package/components/select/demo/keyboardBehavior.html +0 -48
@@ -1,718 +0,0 @@
1
- import { i, a as i$1, b as b$1 } from './registerDemoDeps.min.js';
2
-
3
- var styleCss = i``;
4
-
5
- // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
6
- // See LICENSE in the project root for license information.
7
-
8
- // ---------------------------------------------------------------------
9
-
10
- /* eslint-disable line-comment-position, no-inline-comments, no-confusing-arrow, no-nested-ternary, implicit-arrow-linebreak */
11
-
12
- class AuroLibraryRuntimeUtils {
13
-
14
- /* eslint-disable jsdoc/require-param */
15
-
16
- /**
17
- * This will register a new custom element with the browser.
18
- * @param {String} name - The name of the custom element.
19
- * @param {Object} componentClass - The class to register as a custom element.
20
- * @returns {void}
21
- */
22
- registerComponent(name, componentClass) {
23
- if (!customElements.get(name)) {
24
- customElements.define(name, class extends componentClass {});
25
- }
26
- }
27
-
28
- /**
29
- * Finds and returns the closest HTML Element based on a selector.
30
- * @returns {void}
31
- */
32
- closestElement(
33
- selector, // selector like in .closest()
34
- base = this, // extra functionality to skip a parent
35
- __Closest = (el, found = el && el.closest(selector)) =>
36
- !el || el === document || el === window
37
- ? null // standard .closest() returns null for non-found selectors also
38
- : found
39
- ? found // found a selector INside this element
40
- : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM
41
- ) {
42
- return __Closest(base);
43
- }
44
- /* eslint-enable jsdoc/require-param */
45
-
46
- /**
47
- * If the element passed is registered with a different tag name than what is passed in, the tag name is added as an attribute to the element.
48
- * @param {Object} elem - The element to check.
49
- * @param {String} tagName - The name of the Auro component to check for or add as an attribute.
50
- * @returns {void}
51
- */
52
- handleComponentTagRename(elem, tagName) {
53
- const tag = tagName.toLowerCase();
54
- const elemTag = elem.tagName.toLowerCase();
55
-
56
- if (elemTag !== tag) {
57
- elem.setAttribute(tag, true);
58
- }
59
- }
60
-
61
- /**
62
- * Validates if an element is a specific Auro component.
63
- * @param {Object} elem - The element to validate.
64
- * @param {String} tagName - The name of the Auro component to check against.
65
- * @returns {Boolean} - Returns true if the element is the specified Auro component.
66
- */
67
- elementMatch(elem, tagName) {
68
- const tag = tagName.toLowerCase();
69
- const elemTag = elem.tagName.toLowerCase();
70
-
71
- return elemTag === tag || elem.hasAttribute(tag);
72
- }
73
-
74
- /**
75
- * Gets the text content of a named slot.
76
- * @returns {String}
77
- * @private
78
- */
79
- getSlotText(elem, name) {
80
- const slot = elem.shadowRoot?.querySelector(`slot[name="${name}"]`);
81
- const nodes = slot?.assignedNodes({ flatten: true }) || [];
82
- const text = nodes.map(n => n.textContent?.trim()).join(' ').trim();
83
-
84
- return text || null;
85
- }
86
- }
87
-
88
- /* eslint-disable no-underscore-dangle, max-lines, object-property-newline */
89
-
90
-
91
- /**
92
- * @typedef {Object} FormStateMember - The form state member.
93
- * @property {string | number | boolean | string[] | null} value - The value of the form element.
94
- * @property {ValidityState} validity - The validity state of the form element, stored when fired from the form element.
95
- * @property {boolean} required - Whether the form element is required or not.
96
- * @property {HTMLElement} element - Whether the form element is required or not.
97
- */
98
-
99
- /**
100
- * @typedef {Object.<string, FormStateMember>} FormState - The form state.
101
- */
102
-
103
- /**
104
- * The `auro-form` element provides users a way to create and manage forms in a consistent manner.
105
- * @customElement auro-form
106
- *
107
- * @slot default - The default slot for form elements.
108
- *
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.
113
- */
114
- class AuroForm extends i$1 {
115
- static get properties() {
116
- return {
117
-
118
- /** @private */
119
- formState: { type: Object, attribute: false },
120
-
121
- /** @private */
122
- _validity: { type: Object, attribute: false },
123
-
124
- /** @private */
125
- _isInitialState: { type: Boolean, attribute: false },
126
-
127
- /** @private */
128
- _elements: { type: Array, attribute: false },
129
-
130
- /** @private */
131
- _submitElements: { type: Array, attribute: false },
132
-
133
- /** @private */
134
- _resetElements: { type: Array, attribute: false },
135
- };
136
- }
137
-
138
- constructor() {
139
- super();
140
-
141
- /**
142
- * @type {FormState}
143
- * @private
144
- */
145
- this.formState = {};
146
-
147
- /**
148
- * @type {"valid" | "invalid" | null}
149
- * @private
150
- */
151
- this._validity = null;
152
-
153
- /** @private */
154
- this._isInitialState = true;
155
-
156
- /**
157
- * @type {(HTMLElement & {reset: () => void})[]}
158
- * @private
159
- */
160
- this._elements = [];
161
-
162
- /**
163
- * @type {HTMLButtonElement[]}
164
- * @private
165
- */
166
- this._submitElements = [];
167
-
168
- /**
169
- * @type {HTMLButtonElement[]}
170
- * @private
171
- */
172
- this._resetElements = [];
173
-
174
- /**
175
- * @private
176
- * @type {MutationObserver[]}
177
- */
178
- this.mutationObservers = [];
179
-
180
- // Bind listeners
181
- /** @private */
182
- this.reset = this.reset.bind(this);
183
-
184
- /** @private */
185
- this.submit = this.submit.bind(this);
186
-
187
- /** @private */
188
- this.sharedInputListener = this.sharedInputListener.bind(this);
189
-
190
- /** @private */
191
- this.sharedValidationListener = this.sharedValidationListener.bind(this);
192
-
193
- /** @private */
194
- this.mutationEventListener = this.mutationEventListener.bind(this);
195
-
196
- /** @private */
197
- this.handleKeyDown = this.handleKeyDown.bind(this);
198
- }
199
-
200
- // Note: button is NOT considered a form element in this context
201
- // as it does not have a .value property.
202
- static get formElementTags() {
203
- return [
204
- 'auro-input',
205
- 'auro-select',
206
- 'auro-datepicker',
207
- 'auro-combobox',
208
- // checkbox and radio are grouped elements
209
- 'auro-checkbox-group',
210
- 'auro-radio-group',
211
- // while counter is groupable, the group is for min/max values and not for grouped values
212
- 'auro-counter-group'
213
- ];
214
- }
215
-
216
- /**
217
- * Compare tag name with element to identify it (for API purposes).
218
- * @param {string} elementTag - The HTML tag name like `auro-datepicker`.
219
- * @param {HTMLElement} element - The actual HTML element to compare.
220
- * @returns {boolean}
221
- * @private
222
- */
223
- _isElementTag(elementTag, element) {
224
- return element.tagName.toLowerCase() === elementTag || element.hasAttribute(elementTag.toLowerCase());
225
- }
226
-
227
- /**
228
- * Shared code for determining if an element is something we care about (submit, form element, etc.).
229
- * @param {string[]} collection - The array to use for tag name search.
230
- * @param {HTMLElement} element - The element to compare against the master list.
231
- * @returns {boolean}
232
- * @private
233
- */
234
- _isInElementCollection(collection, element) {
235
- return collection.some((elementTag) => this._isElementTag(elementTag, element));
236
- }
237
-
238
- /**
239
- * Check if the tag name is a form element.
240
- * @param {HTMLElement} element - The element to check (attr or tag name).
241
- * @returns {boolean}
242
- * @private
243
- */
244
- isFormElement(element) {
245
- return this._isInElementCollection(AuroForm.formElementTags, element);
246
- }
247
-
248
- /**
249
- * Validates if an event is from a valid form element with a name.
250
- * @param {Event} event - The event to validate.
251
- * @returns {boolean} - True if event is valid for processing.
252
- * @private
253
- */
254
- _eventIsValidFormEvent(event) {
255
- const targetName = event.target.getAttribute("name");
256
- return this.isFormElement(event.target) && targetName;
257
- }
258
-
259
-
260
- static get buttonElementTags() {
261
- return [
262
- 'button',
263
- 'auro-button',
264
- ];
265
- }
266
-
267
- /**
268
- * Check if the tag name is a button element.
269
- * @param {HTMLElement} element - The element to check.
270
- * @returns {boolean}
271
- * @private
272
- */
273
- isButtonElement(element) {
274
- return this._isInElementCollection(AuroForm.buttonElementTags, element);
275
- }
276
-
277
- static get styles() {
278
- return [styleCss];
279
- }
280
-
281
- /**
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.
284
- */
285
- get value() {
286
- return Object.keys(this.formState).reduce((acc, key) => {
287
- acc[key] = this.formState[key].value;
288
- return acc;
289
- }, {});
290
- }
291
-
292
- /**
293
- * Getter for internal _submitElements.
294
- * @returns {HTMLButtonElement[]}
295
- * @private
296
- */
297
- get submitElements() {
298
- return this._submitElements;
299
- }
300
-
301
- /**
302
- * Returns a collection of elements that will reset the form.
303
- * @returns {HTMLButtonElement[]}
304
- * @private
305
- */
306
- get resetElements() {
307
- return this._resetElements;
308
- }
309
-
310
- /**
311
- * Infer validity status based on current formState.
312
- * @private
313
- */
314
- _calculateValidity() {
315
- if (this.isInitialState) {
316
- this._validity = null;
317
- } else {
318
- // go through validity states and return the first invalid state (if any)
319
- const invalidKey = Object.keys(this.formState).
320
- find((key) => {
321
- const formKey = this.formState[key];
322
- // these are NOT extra parens
323
- // eslint-disable-next-line no-extra-parens
324
- return (formKey.validity !== 'valid' && formKey.required) || (formKey.validity !== 'valid' && formKey.value !== null);
325
- });
326
- this._validity = invalidKey ? 'invalid' : 'valid';
327
- }
328
- }
329
-
330
- /**
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}
333
- */
334
- get validity() {
335
- // Force calculate, as sometimes validity won't reflect
336
- // the latest value while in-between renders.
337
- this._calculateValidity();
338
- return this._validity;
339
- }
340
-
341
- /**
342
- * Determines whether the form is in its initial (untouched) state and updates `_isInitialState` accordingly.
343
- * @returns {void}
344
- * @private
345
- */
346
- _setInitialState() {
347
- const anyTainted = Object.keys(this.formState).some((key) => this.formState[key].validity !== null || this.formState[key].value !== null);
348
-
349
- this._isInitialState = !anyTainted;
350
-
351
- this._resetElements.forEach((resetElement) => {
352
- if (resetElement.hasAttribute("disabled")) {
353
- resetElement.removeAttribute("disabled");
354
- }
355
- });
356
- }
357
-
358
- /**
359
- * Returns `true` if no form element has been interacted with or had its value changed since the form was initialized or last reset.
360
- * @returns {boolean}
361
- */
362
- get isInitialState() {
363
- return this._isInitialState;
364
- }
365
-
366
- /**
367
- * Enables or disables submit and reset buttons based on the current form state and validity.
368
- * @returns {void}
369
- * @private
370
- */
371
- setDisabledStateOnButtons() {
372
- this._resetElements.forEach((element) => {
373
- if (this.isInitialState) {
374
- element.setAttribute("disabled", "");
375
- } else {
376
- element.removeAttribute("disabled");
377
- }
378
- });
379
-
380
- this._submitElements.forEach((element) => {
381
- if (this.isInitialState || this.validity !== "valid") {
382
- element.setAttribute("disabled", "");
383
- } else {
384
- element.removeAttribute("disabled");
385
- }
386
- });
387
- }
388
-
389
- /**
390
- * Construct the query strings from elements, append them together, execute, and return the NodeList.
391
- * @returns {NodeList}
392
- * @private
393
- */
394
- queryAuroElements() {
395
- const queries = [
396
- [
397
- AuroForm.formElementTags,
398
- '[name]'
399
- ],
400
- [
401
- AuroForm.buttonElementTags,
402
- '[type=submit]'
403
- ],
404
- [
405
- AuroForm.buttonElementTags,
406
- '[type=reset]'
407
- ]
408
- ];
409
-
410
- return this.querySelectorAll(queries.flatMap(([
411
- tags,
412
- extraAttributes
413
- ]) => tags.map((tag) => `${tag}${extraAttributes}, [${tag}]${extraAttributes}`)).join(', '));
414
- }
415
-
416
- /**
417
- * Store an element in state and on the _elements array.
418
- * @param {HTMLElement} element - The element to add to our state.
419
- * @private
420
- */
421
- _addElementToState(element) {
422
- const targetName = element.getAttribute('name');
423
- if (this.formState[targetName]) {
424
- return;
425
- }
426
-
427
- this.formState[targetName] = {
428
- value: element.value || element.getAttribute('value'),
429
- validity: element.validity || null,
430
- required: element.hasAttribute('required'),
431
- // element
432
- };
433
-
434
- this._elements.push(element);
435
- }
436
-
437
- /**
438
- * Initialize (or reinitialize) the form state.
439
- * @returns {void}
440
- * @private
441
- */
442
- initializeState() {
443
- this.formState = {};
444
- this._submitElements = [];
445
- this._resetElements = [];
446
- this._elements = [];
447
-
448
- this.queryAuroElements().forEach((element) => {
449
- if (this.isFormElement(element)) {
450
- this._addElementToState(element);
451
- }
452
-
453
- if (this.isButtonElement(element) && element.getAttribute('type') === 'submit') {
454
- element.removeEventListener('click', this.submit);
455
- element.addEventListener('click', this.submit);
456
-
457
- // Keep record of this element, so we can enable/disable as needed
458
- this._submitElements.push(element);
459
- }
460
-
461
- if (this.isButtonElement(element) && element.getAttribute('type') === 'reset') {
462
- // Keep record of this element, so we can enable/disable as needed
463
- element.removeEventListener('click', this.reset);
464
- element.addEventListener('click', this.reset);
465
-
466
- this._resetElements.push(element);
467
- }
468
- });
469
-
470
- this.dispatchEvent(new Event('change', {
471
- bubbles: true,
472
- composed: true,
473
- cancelable: true
474
- }));
475
-
476
- // Set enabled/disabled states on buttons
477
- this.setDisabledStateOnButtons();
478
- }
479
-
480
- /**
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}
483
- */
484
- reset() {
485
- const previousValue = this.value;
486
- this._elements.forEach((element) => element.reset());
487
-
488
- this.updateComplete.then(() => {
489
- this.initializeState();
490
- // Initial state must come first - validity can only be null if initial state is true
491
- this._setInitialState();
492
- this._calculateValidity();
493
-
494
- // Wait for the above changes to run through, then disable submit/reset
495
- this.updateComplete.then(() => {
496
- this.setDisabledStateOnButtons();
497
-
498
- this.dispatchEvent(new CustomEvent('reset', {
499
- bubbles: true,
500
- composed: true,
501
- detail: {
502
- previousValue
503
- }
504
- }));
505
- });
506
- });
507
- }
508
-
509
- /**
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>}
512
- */
513
- async submit() {
514
- // Force validation on ALL elements
515
- this._elements.forEach((element) => {
516
- element.validate(true);
517
- });
518
-
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
- }
532
- }
533
-
534
- /**
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.
537
- *
538
- * @example
539
- * AuroForm.register("custom-form") // registers as <custom-form>
540
- */
541
- static register(name = "auro-form") {
542
- AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroForm);
543
- }
544
-
545
- /**
546
- * Shared input listener for all form elements.
547
- * @param {Event} event - The event that is fired from the form element.
548
- * @private
549
- */
550
- sharedInputListener(event) {
551
- const targetName = event.target.getAttribute("name");
552
-
553
- // This should only happen if some bubble-up event is fired from inside a form element.
554
- if (!this._eventIsValidFormEvent(event)) {
555
- return;
556
- }
557
-
558
- // Occasionally, a form element will emit their event before the form can read data about the form element.
559
- if (!this.formState[targetName] && this.isFormElement(event.target)) {
560
- this._addElementToState(event.target);
561
- }
562
-
563
- // Check special input types and handle their edge cases
564
- if (this._isElementTag('auro-datepicker', event.target) && event.target.hasAttribute('range')) {
565
- this.formState[targetName].value = event.target.values;
566
- } else {
567
- this.formState[targetName].value = event.target.value;
568
- }
569
-
570
- this.requestUpdate('formState');
571
- this.dispatchEvent(new CustomEvent('change', {
572
- bubbles: true,
573
- composed: true,
574
- cancelable: true
575
- }));
576
- }
577
-
578
- /**
579
- * Shared validation listener for all form elements.
580
- * @param {Event} event - The event that is fired from the form element.
581
- * @private
582
- */
583
- sharedValidationListener(event) {
584
- const targetName = event.target.getAttribute("name");
585
- if (!this._eventIsValidFormEvent(event)) {
586
- return;
587
- }
588
-
589
- if (!this.formState[targetName]) {
590
- this._addElementToState(event.target);
591
- }
592
-
593
- this.formState[targetName].validity = event.detail.validity;
594
- this._calculateValidity();
595
- this.requestUpdate('formState');
596
- }
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
- */
622
- _attachEventListeners() {
623
- this.queryAuroElements().forEach((element) => {
624
- // remove any existing event listeners (in case of re-initialization)
625
- element.removeEventListener('input', this.sharedInputListener);
626
- element.removeEventListener('auroFormElement-validated', this.sharedValidationListener);
627
- element.removeEventListener('keydown', this.handleKeyDown);
628
-
629
- // add new event listeners
630
- element.addEventListener('input', this.sharedInputListener);
631
- element.addEventListener('auroFormElement-validated', this.sharedValidationListener);
632
- element.addEventListener('keydown', this.handleKeyDown);
633
- });
634
- }
635
-
636
- /**
637
- * @param {import('lit').PropertyValues} _changedProperties - Map of changed properties with their previous values.
638
- * @returns {void}
639
- */
640
- firstUpdated(_changedProperties) {
641
- super.firstUpdated(_changedProperties);
642
-
643
- this._attachEventListeners();
644
- }
645
-
646
- /**
647
- * @param {import('lit').PropertyValues} _changedProperties - Map of changed properties with their previous values.
648
- * @returns {void}
649
- */
650
- updated(_changedProperties) {
651
- super.updated(_changedProperties);
652
-
653
- if (_changedProperties.has("formState")) {
654
- this._setInitialState();
655
-
656
- // Automatically infer disabled state now
657
- this.setDisabledStateOnButtons();
658
- }
659
-
660
- if (_changedProperties.has("_validity")) {
661
- this._setInitialState();
662
- }
663
- }
664
-
665
- /**
666
- * Mutation observer for form elements. Slot change does not trigger unless
667
- * root-level elements are added/removed. This is a workaround to ensure
668
- * nested form elements are also observed.
669
- *
670
- * @returns {void}
671
- * @private
672
- */
673
- mutationEventListener() {
674
- this.initializeState();
675
- this._attachEventListeners();
676
- }
677
-
678
- /**
679
- * Slot change event listener. This is the main entry point for the form element.
680
- * @param {Event} event - The slot change event.
681
- * @returns {void}
682
- * @private
683
- */
684
- onSlotChange(event) {
685
- this.initializeState();
686
- // Safe to call as we remove and re-add event listeners
687
- this._attachEventListeners();
688
-
689
- // Get rid of old observers - we'll create new ones in a moment
690
- this.mutationObservers.forEach((mo) => mo.disconnect());
691
- this.mutationObservers = [];
692
-
693
- const slotNodes = event.currentTarget.assignedNodes();
694
- slotNodes.forEach((node) => {
695
- if (node.tagName && !this.isFormElement(node)) {
696
- const mo = new MutationObserver(this.mutationEventListener);
697
- mo.observe(node, {
698
- subtree: true,
699
- childList: true
700
- });
701
- this.mutationObservers.push(mo);
702
- }
703
- });
704
- }
705
-
706
- /**
707
- * @returns {import('lit').TemplateResult}
708
- */
709
- render() {
710
- return b$1`
711
- <form>
712
- <slot @slotchange="${this.onSlotChange}"></slot>
713
- </form>
714
- `;
715
- }
716
- }
717
-
718
- export { AuroForm as A };