@aurodesignsystem-dev/auro-formkit 0.0.0-pr1510.3 → 0.0.0-pr1512.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 (129) hide show
  1. package/components/checkbox/demo/customize.js +22 -0
  2. package/components/checkbox/demo/customize.min.js +1 -1
  3. package/components/checkbox/demo/demo-support.js +1 -0
  4. package/components/checkbox/demo/getting-started.js +22 -0
  5. package/components/checkbox/demo/getting-started.min.js +1 -1
  6. package/components/checkbox/demo/index.js +8 -0
  7. package/components/checkbox/demo/index.min.js +1 -1
  8. package/components/checkbox/demo/styles.scss +1 -0
  9. package/components/checkbox/dist/index.js +1 -1
  10. package/components/checkbox/dist/registered.js +1 -1
  11. package/components/combobox/demo/customize.js +24 -0
  12. package/components/combobox/demo/customize.min.js +119 -96
  13. package/components/combobox/demo/demo-support.js +1 -0
  14. package/components/combobox/demo/getting-started.js +21 -0
  15. package/components/combobox/demo/getting-started.min.js +119 -96
  16. package/components/combobox/demo/index.js +23 -0
  17. package/components/combobox/demo/index.min.js +119 -96
  18. package/components/combobox/demo/styles.scss +1 -0
  19. package/components/combobox/dist/index.js +118 -95
  20. package/components/combobox/dist/registered.js +118 -95
  21. package/components/counter/demo/customize.js +21 -0
  22. package/components/counter/demo/customize.min.js +2 -2
  23. package/components/counter/demo/demo-support.js +1 -0
  24. package/components/counter/demo/index.js +21 -0
  25. package/components/counter/demo/index.min.js +2 -2
  26. package/components/counter/demo/styles.scss +1 -0
  27. package/components/counter/dist/index.js +2 -2
  28. package/components/counter/dist/registered.js +2 -2
  29. package/components/datepicker/demo/accessibility.md +1 -2
  30. package/components/datepicker/demo/api.md +62 -63
  31. package/components/datepicker/demo/customize.js +17 -0
  32. package/components/datepicker/demo/customize.md +1 -12
  33. package/components/datepicker/demo/customize.min.js +335 -702
  34. package/components/datepicker/demo/demo-support.js +1 -0
  35. package/components/datepicker/demo/index.js +23 -0
  36. package/components/datepicker/demo/index.min.js +335 -702
  37. package/components/datepicker/demo/styles.scss +1 -0
  38. package/components/datepicker/dist/index.js +335 -702
  39. package/components/datepicker/dist/registered.js +335 -702
  40. package/components/datepicker/dist/{auro-calendar-cell.d.ts → src/auro-calendar-cell.d.ts} +3 -14
  41. package/components/datepicker/dist/{auro-calendar.d.ts → src/auro-calendar.d.ts} +6 -90
  42. package/components/datepicker/dist/{auro-datepicker.d.ts → src/auro-datepicker.d.ts} +5 -78
  43. package/components/dropdown/demo/customize.js +9 -0
  44. package/components/dropdown/demo/customize.min.js +1 -1
  45. package/components/dropdown/demo/demo-support.js +1 -0
  46. package/components/dropdown/demo/getting-started.js +9 -0
  47. package/components/dropdown/demo/getting-started.min.js +1 -1
  48. package/components/dropdown/demo/index.js +16 -0
  49. package/components/dropdown/demo/index.min.js +1 -1
  50. package/components/dropdown/demo/styles.scss +1 -0
  51. package/components/dropdown/dist/index.js +1 -1
  52. package/components/dropdown/dist/registered.js +1 -1
  53. package/components/form/demo/customize.js +28 -0
  54. package/components/form/demo/customize.min.js +583 -904
  55. package/components/form/demo/demo-support.js +1 -0
  56. package/components/form/demo/getting-started.js +9 -0
  57. package/components/form/demo/getting-started.min.js +583 -904
  58. package/components/form/demo/index.js +5 -0
  59. package/components/form/demo/index.min.js +583 -904
  60. package/components/form/demo/registerDemoDeps.js +23 -0
  61. package/components/form/demo/registerDemoDeps.min.js +583 -904
  62. package/components/form/demo/styles.scss +1 -0
  63. package/components/input/demo/api.md +5 -5
  64. package/components/input/demo/customize.js +25 -0
  65. package/components/input/demo/customize.md +8 -8
  66. package/components/input/demo/customize.min.js +116 -93
  67. package/components/input/demo/demo-support.js +1 -0
  68. package/components/input/demo/getting-started.js +8 -0
  69. package/components/input/demo/getting-started.min.js +116 -93
  70. package/components/input/demo/index.js +8 -0
  71. package/components/input/demo/index.min.js +116 -93
  72. package/components/input/demo/styles.css +974 -0
  73. package/components/input/demo/styles.scss +1 -0
  74. package/components/input/dist/base-input.d.ts +33 -44
  75. package/components/input/dist/index.js +129 -94
  76. package/components/input/dist/registered.js +116 -93
  77. package/components/menu/demo/demo-support.js +1 -0
  78. package/components/menu/demo/index.js +25 -0
  79. package/components/menu/demo/styles.scss +1 -0
  80. package/components/radio/demo/customize.js +22 -0
  81. package/components/radio/demo/customize.min.js +1 -1
  82. package/components/radio/demo/demo-support.js +1 -0
  83. package/components/radio/demo/getting-started.js +24 -0
  84. package/components/radio/demo/getting-started.min.js +1 -1
  85. package/components/radio/demo/index.js +8 -0
  86. package/components/radio/demo/index.min.js +1 -1
  87. package/components/radio/demo/styles.scss +1 -0
  88. package/components/radio/dist/index.js +1 -1
  89. package/components/radio/dist/registered.js +1 -1
  90. package/components/select/demo/customize.js +11 -0
  91. package/components/select/demo/customize.min.js +2 -2
  92. package/components/select/demo/demo-support.js +1 -0
  93. package/components/select/demo/getting-started.js +26 -0
  94. package/components/select/demo/getting-started.min.js +2 -2
  95. package/components/select/demo/index.js +11 -0
  96. package/components/select/demo/index.min.js +2 -2
  97. package/components/select/demo/styles.scss +1 -0
  98. package/components/select/dist/index.js +2 -2
  99. package/components/select/dist/registered.js +2 -2
  100. package/custom-elements.json +2146 -2218
  101. package/package.json +2 -6
  102. package/components/datepicker/dist/blackoutUtils.d.ts +0 -43
  103. /package/components/datepicker/dist/{auro-calendar-month.d.ts → src/auro-calendar-month.d.ts} +0 -0
  104. /package/components/datepicker/dist/{buttonVersion.d.ts → src/buttonVersion.d.ts} +0 -0
  105. /package/components/datepicker/dist/{datepickerKeyboardStrategy.d.ts → src/datepickerKeyboardStrategy.d.ts} +0 -0
  106. /package/components/datepicker/dist/{iconVersion.d.ts → src/iconVersion.d.ts} +0 -0
  107. /package/components/datepicker/dist/{index.d.ts → src/index.d.ts} +0 -0
  108. /package/components/datepicker/dist/{popoverVersion.d.ts → src/popoverVersion.d.ts} +0 -0
  109. /package/components/datepicker/dist/{styles → src/styles}/classic/color-css.d.ts +0 -0
  110. /package/components/datepicker/dist/{styles → src/styles}/classic/style-css.d.ts +0 -0
  111. /package/components/datepicker/dist/{styles → src/styles}/color-calendar-css.d.ts +0 -0
  112. /package/components/datepicker/dist/{styles → src/styles}/color-cell-css.d.ts +0 -0
  113. /package/components/datepicker/dist/{styles → src/styles}/color-css.d.ts +0 -0
  114. /package/components/datepicker/dist/{styles → src/styles}/color-month-css.d.ts +0 -0
  115. /package/components/datepicker/dist/{styles → src/styles}/shapeSize-css.d.ts +0 -0
  116. /package/components/datepicker/dist/{styles → src/styles}/snowflake/color-css.d.ts +0 -0
  117. /package/components/datepicker/dist/{styles → src/styles}/snowflake/style-css.d.ts +0 -0
  118. /package/components/datepicker/dist/{styles → src/styles}/style-auro-calendar-cell-css.d.ts +0 -0
  119. /package/components/datepicker/dist/{styles → src/styles}/style-auro-calendar-css.d.ts +0 -0
  120. /package/components/datepicker/dist/{styles → src/styles}/style-auro-calendar-month-css.d.ts +0 -0
  121. /package/components/datepicker/dist/{styles → src/styles}/style-css.d.ts +0 -0
  122. /package/components/datepicker/dist/{styles → src/styles}/tokens-css.d.ts +0 -0
  123. /package/components/datepicker/dist/{utilities.d.ts → src/utilities.d.ts} +0 -0
  124. /package/components/datepicker/dist/{utilitiesCalendar.d.ts → src/utilitiesCalendar.d.ts} +0 -0
  125. /package/components/datepicker/dist/{utilitiesCalendarRender.d.ts → src/utilitiesCalendarRender.d.ts} +0 -0
  126. /package/components/datepicker/dist/{vendor → src/vendor}/wc-range-datepicker/day.d.ts +0 -0
  127. /package/components/datepicker/dist/{vendor → src/vendor}/wc-range-datepicker/range-datepicker-calendar.d.ts +0 -0
  128. /package/components/datepicker/dist/{vendor → src/vendor}/wc-range-datepicker/range-datepicker-cell.d.ts +0 -0
  129. /package/components/datepicker/dist/{vendor → src/vendor}/wc-range-datepicker/range-datepicker.d.ts +0 -0
@@ -0,0 +1 @@
1
+ @import '@aurodesignsystem/config/demo-styles';
@@ -382,8 +382,23 @@ export default class BaseInput extends AuroElement {
382
382
  reflect: boolean;
383
383
  };
384
384
  };
385
+ activeLabel: boolean;
386
+ /** @private */
387
+ private allowedInputTypes;
385
388
  appearance: string;
389
+ /** @private */
390
+ private dateFormatMap;
386
391
  disabled: boolean;
392
+ /** @private */
393
+ private domHandler;
394
+ dvInputOnly: boolean;
395
+ hasValue: boolean;
396
+ hideLabelVisually: boolean;
397
+ icon: boolean;
398
+ /** @private */
399
+ private inputIconName;
400
+ /** @private */
401
+ private label;
387
402
  locale: string;
388
403
  max: any;
389
404
  _maxObject: any;
@@ -391,53 +406,28 @@ export default class BaseInput extends AuroElement {
391
406
  min: any;
392
407
  _minObject: any;
393
408
  minLength: any;
394
- required: boolean;
409
+ noValidate: boolean;
395
410
  onDark: boolean;
411
+ _rawMaskValue: string | undefined;
412
+ required: boolean;
396
413
  setCustomValidityForType: string | undefined;
397
- size: string;
414
+ /** @private */
415
+ private setSelectionInputTypes;
398
416
  shape: string;
417
+ /** @private */
418
+ private showPassword;
419
+ size: string;
420
+ touched: boolean;
421
+ /** @private */
422
+ private uniqueId;
423
+ /** @private */
424
+ private util;
425
+ /** @private */
426
+ private validation;
427
+ /** @private */
428
+ private validationCCLength;
399
429
  value: any;
400
430
  _valueObject: any;
401
- /**
402
- * Internal Defaults.
403
- * @private
404
- * @returns {void}
405
- */
406
- private _initializePrivateDefaults;
407
- activeLabel: boolean | undefined;
408
- icon: boolean | undefined;
409
- dvInputOnly: boolean | undefined;
410
- hideLabelVisually: boolean | undefined;
411
- noValidate: boolean | undefined;
412
- _rawMaskValue: string | undefined;
413
- touched: boolean | undefined;
414
- util: any;
415
- validation: AuroFormValidation | undefined;
416
- inputIconName: any;
417
- showPassword: boolean | undefined;
418
- validationCCLength: number | undefined;
419
- hasValue: boolean | undefined;
420
- label: string | undefined;
421
- allowedInputTypes: string[] | undefined;
422
- dateFormatMap: {
423
- 'mm/dd/yyyy': string;
424
- 'dd/mm/yyyy': string;
425
- 'yyyy/mm/dd': string;
426
- 'yyyy/dd/mm': string;
427
- 'mm/yy': string;
428
- 'yy/mm': string;
429
- 'mm/yyyy': string;
430
- 'yyyy/mm': string;
431
- yy: string;
432
- yyyy: string;
433
- mm: string;
434
- dd: string;
435
- 'dd/mm': string;
436
- 'mm/dd': string;
437
- } | undefined;
438
- domHandler: any;
439
- setSelectionInputTypes: string[] | undefined;
440
- uniqueId: any;
441
431
  /**
442
432
  * Read-only Date object representation of `value` for full date formats.
443
433
  * @returns {Date|undefined}
@@ -481,6 +471,7 @@ export default class BaseInput extends AuroElement {
481
471
  inputElement: HTMLInputElement | null | undefined;
482
472
  labelElement: HTMLLabelElement | null | undefined;
483
473
  inputId: string | undefined;
474
+ format: any;
484
475
  ValidityMessageOverride: any;
485
476
  /**
486
477
  * Patches the input element to dispatch an 'input' event whenever its value is set programmatically.
@@ -503,7 +494,6 @@ export default class BaseInput extends AuroElement {
503
494
  * @returns {void}
504
495
  */
505
496
  updated(changedProperties: Map<string, any>): void;
506
- format: any;
507
497
  skipNextProgrammaticInputEvent: boolean | undefined;
508
498
  /**
509
499
  * @private
@@ -648,4 +638,3 @@ export default class BaseInput extends AuroElement {
648
638
  private matchInputValueToCreditCard;
649
639
  }
650
640
  import { AuroElement } from '../../layoutElement/src/auroElement.js';
651
- import AuroFormValidation from '@aurodesignsystem/form-validation';
@@ -10327,6 +10327,13 @@ class AuroInputUtilities {
10327
10327
  * @returns {string | undefined}
10328
10328
  */
10329
10329
  toFormattedValue(valueObject, format) {
10330
+ // Exposed publicly via `AuroInputUtil.toFormattedValue`, so a missing
10331
+ // `format` argument has to fail gracefully rather than throw on
10332
+ // `format.toLowerCase()`. Treat any falsy value (undefined, null, '')
10333
+ // as "no format → no display value".
10334
+ if (!format) {
10335
+ return undefined;
10336
+ }
10330
10337
  const normalizedFormat = format.toLowerCase();
10331
10338
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10332
10339
 
@@ -10477,79 +10484,18 @@ class BaseInput extends AuroElement {
10477
10484
  constructor() {
10478
10485
  super();
10479
10486
 
10480
- this.appearance = "default";
10481
- this.disabled = false;
10482
- this.layout = 'classic';
10483
- this.locale = 'en-US';
10484
- this.max = undefined;
10485
- this._maxObject = undefined;
10486
- this.maxLength = undefined;
10487
- this.min = undefined;
10488
- this._minObject = undefined;
10489
- this.minLength = undefined;
10490
- this.required = false;
10491
- this.onDark = false;
10492
- this.setCustomValidityForType = undefined;
10493
- this.size = 'lg';
10494
- this.shape = 'classic';
10495
- this.value = undefined;
10496
- this._valueObject = undefined;
10497
-
10498
- this._initializePrivateDefaults();
10499
- }
10500
-
10501
- /**
10502
- * Internal Defaults.
10503
- * @private
10504
- * @returns {void}
10505
- */
10506
- _initializePrivateDefaults() {
10487
+ // Single-source initialization. Alphabetized so duplicate or stale
10488
+ // defaults are immediately obvious on a diff. Every field is assigned
10489
+ // exactly once here (previously the constructor + the old
10490
+ // `_initializePrivateDefaults` overlapped — both wrote ~14 of the same
10491
+ // fields and double-allocated `util` and `validation`, discarding the
10492
+ // first instance). `validation` is now allocated exactly once; `util`
10493
+ // is seeded here with an en-US default and then rebuilt in
10494
+ // `connectedCallback` once the consumer-resolved locale is available,
10495
+ // so a parent (datepicker/combobox) calling `validate()` synchronously
10496
+ // during its own update cycle sees a populated util instance.
10507
10497
  this.activeLabel = false;
10508
- this.appearance = "default";
10509
- this.icon = false;
10510
- this.disabled = false;
10511
- this.dvInputOnly = false;
10512
- this.hideLabelVisually = false;
10513
- this.max = undefined;
10514
- this.maxLength = undefined;
10515
- this.min = undefined;
10516
- this.minLength = undefined;
10517
- this.noValidate = false;
10518
- this.onDark = false;
10519
- this.required = false;
10520
- this.setCustomValidityForType = undefined;
10521
-
10522
- // Used for storing raw values returned from input mask.
10523
- this._rawMaskValue = undefined;
10524
-
10525
- /**
10526
- * @private
10527
- */
10528
- this.layout = 'classic';
10529
-
10530
- /**
10531
- * @private
10532
- */
10533
- this.shape = 'classic';
10534
-
10535
- /**
10536
- * @private
10537
- */
10538
- this.size = 'lg';
10539
-
10540
- this.touched = false;
10541
- this.util = new AuroInputUtilities({
10542
- locale: "en-US",
10543
- format: this.format
10544
- });
10545
- this.validation = new AuroFormValidation();
10546
- this.inputIconName = undefined;
10547
- this.showPassword = false;
10548
- this.validationCCLength = undefined;
10549
- this.hasValue = false;
10550
- this.label = 'Input label is undefined';
10551
-
10552
-
10498
+ /** @private */
10553
10499
  this.allowedInputTypes = [
10554
10500
  "text",
10555
10501
  "number",
@@ -10558,7 +10504,8 @@ class BaseInput extends AuroElement {
10558
10504
  "credit-card",
10559
10505
  "tel"
10560
10506
  ];
10561
- this.icon = false;
10507
+ this.appearance = "default";
10508
+ /** @private */
10562
10509
  this.dateFormatMap = {
10563
10510
  'mm/dd/yyyy': 'dateMMDDYYYY',
10564
10511
  'dd/mm/yyyy': 'dateDDMMYYYY',
@@ -10575,27 +10522,57 @@ class BaseInput extends AuroElement {
10575
10522
  'dd/mm': 'dateDDMM',
10576
10523
  'mm/dd': 'dateMMDD'
10577
10524
  };
10525
+ this.disabled = false;
10526
+ /** @private */
10578
10527
  this.domHandler = new DomHandler();
10579
10528
  this.dvInputOnly = false;
10580
10529
  this.hasValue = false;
10530
+ this.hideLabelVisually = false;
10531
+ this.icon = false;
10532
+ /** @private */
10581
10533
  this.inputIconName = undefined;
10534
+ /** @private */
10582
10535
  this.label = 'Input label is undefined';
10536
+ this.layout = 'classic';
10537
+ this.locale = 'en-US';
10538
+ this.max = undefined;
10539
+ this._maxObject = undefined;
10540
+ this.maxLength = undefined;
10541
+ this.min = undefined;
10542
+ this._minObject = undefined;
10543
+ this.minLength = undefined;
10583
10544
  this.noValidate = false;
10584
- this._rawMaskValue = undefined; // Used for storing raw values returned from input mask.
10545
+ this.onDark = false;
10546
+ // Raw values returned from the input mask before model normalization.
10547
+ this._rawMaskValue = undefined;
10548
+ this.required = false;
10549
+ this.setCustomValidityForType = undefined;
10550
+ // Credit Card is intentionally excluded — its mask manages the cursor
10551
+ // itself, and listing it here caused cursor placement issues in Safari.
10552
+ /** @private */
10585
10553
  this.setSelectionInputTypes = [
10586
10554
  "text",
10587
10555
  "password",
10588
10556
  "email"
10589
- ]; // Credit Card is not included as this caused cursor placement issues in Safari.
10557
+ ];
10558
+ this.shape = 'classic';
10559
+ /** @private */
10590
10560
  this.showPassword = false;
10561
+ this.size = 'lg';
10591
10562
  this.touched = false;
10563
+ /** @private */
10592
10564
  this.uniqueId = new UniqueId().create();
10565
+ /** @private */
10593
10566
  this.util = new AuroInputUtilities({
10594
10567
  locale: this.locale,
10595
10568
  format: this.format
10596
10569
  });
10570
+ /** @private */
10597
10571
  this.validation = new AuroFormValidation();
10572
+ /** @private */
10598
10573
  this.validationCCLength = undefined;
10574
+ this.value = undefined;
10575
+ this._valueObject = undefined;
10599
10576
  }
10600
10577
 
10601
10578
  // function to define props used within the scope of this component
@@ -11143,6 +11120,15 @@ class BaseInput extends AuroElement {
11143
11120
 
11144
11121
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
11145
11122
 
11123
+ // Normalize the format token to lowercase so case-mixed values supplied
11124
+ // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
11125
+ // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
11126
+ // format silently misses the map and leaves `setCustomValidityForType`
11127
+ // unset.
11128
+ if (this.format) {
11129
+ this.format = this.format.toLowerCase();
11130
+ }
11131
+
11146
11132
  // use validity message override if declared when initializing the component
11147
11133
  if (this.hasAttribute('setCustomValidity')) {
11148
11134
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -11576,6 +11562,38 @@ class BaseInput extends AuroElement {
11576
11562
  this.touched = true;
11577
11563
  this.validation.validate(this);
11578
11564
  }
11565
+
11566
+ // Prevents cursor jumping in Safari. Setting `this.value` triggers a Lit
11567
+ // update that can re-render the input and reset the native cursor; we
11568
+ // capture the caret position before that update commits and restore it
11569
+ // via `setSelectionRange` once the update has flushed. Gated on
11570
+ // `setSelectionInputTypes` so credit-card (and other masked types whose
11571
+ // formatter manages the cursor itself) doesn't get a competing write.
11572
+ // Capture the caret position INSIDE the gate — reading `selectionStart`
11573
+ // on input types that don't support text selection (number, email in
11574
+ // some browsers) throws InvalidStateError, which would crash all input
11575
+ // handling. Wrap the read in try/catch belt-and-suspenders even though
11576
+ // the gated types currently support it, since the list is a public
11577
+ // property a consumer could mutate.
11578
+ if (this.setSelectionInputTypes.includes(this.type)) {
11579
+ let selectionStart;
11580
+ try {
11581
+ selectionStart = this.inputElement.selectionStart;
11582
+ } catch (error) { // eslint-disable-line no-unused-vars
11583
+ return;
11584
+ }
11585
+ if (typeof selectionStart !== 'number') {
11586
+ return;
11587
+ }
11588
+ this.updateComplete.then(() => {
11589
+ try {
11590
+ this.inputElement.setSelectionRange(selectionStart, selectionStart);
11591
+ } catch (error) { // eslint-disable-line no-unused-vars
11592
+ // Some input types (number/email in certain UAs) throw on
11593
+ // setSelectionRange; swallow and let the native cursor stand.
11594
+ }
11595
+ });
11596
+ }
11579
11597
  }
11580
11598
 
11581
11599
  /**
@@ -12202,7 +12220,7 @@ class AuroHelpText extends LitElement {
12202
12220
  }
12203
12221
  }
12204
12222
 
12205
- var formkitVersion = '202606252324';
12223
+ var formkitVersion = '202606252337';
12206
12224
 
12207
12225
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12208
12226
  // See LICENSE in the project root for license information.
@@ -12705,6 +12723,7 @@ class AuroInput extends BaseInput {
12705
12723
  <${this.buttonTag}
12706
12724
  @click="${this.handleClickShowPassword}"
12707
12725
  appearance="${this.onDark ? 'inverse' : this.appearance}"
12726
+ aria-pressed="${this.showPassword ? 'true' : 'false'}"
12708
12727
  class="notificationBtn passwordBtn"
12709
12728
  shape="circle"
12710
12729
  size="sm"
@@ -12778,25 +12797,29 @@ class AuroInput extends BaseInput {
12778
12797
  * @returns {html} - Returns HTML for the help text and error message.
12779
12798
  */
12780
12799
  renderHtmlHelpText() {
12800
+ // Single `<p>` with stable identity across validity transitions —
12801
+ // previously two distinct templates (valid vs invalid) caused Lit to
12802
+ // replace the node entirely on a flip, and VoiceOver wouldn't
12803
+ // re-announce because the live-region element it was watching had been
12804
+ // removed and a new one inserted. Keeping one node means the `role`,
12805
+ // `aria-live`, and text content all change in-place, which AT does
12806
+ // observe and announce.
12807
+ const isError = this.validity && this.validity !== 'valid';
12781
12808
  return html$1`
12782
- ${!this.validity || this.validity === undefined || this.validity === 'valid'
12783
- ? html$1`
12784
- <${this.helpTextTag}
12785
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12786
- <p id="${this.uniqueId}" part="helpText">
12787
- <slot name="helpText">${this.getHelpText()}</slot>
12788
- </p>
12789
- </${this.helpTextTag}>
12790
- `
12791
- : html$1`
12792
- <${this.helpTextTag} error
12793
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12794
- <p id="${this.uniqueId}" role="alert" aria-live="assertive" part="helpText">
12795
- ${this.errorMessage}
12796
- </p>
12797
- </${this.helpTextTag}>
12798
- `
12809
+ <${this.helpTextTag}
12810
+ appearance="${this.onDark ? 'inverse' : this.appearance}"
12811
+ ?error=${isError}>
12812
+ <p
12813
+ id="${this.uniqueId}"
12814
+ part="helpText"
12815
+ role="${ifDefined(isError ? 'alert' : undefined)}"
12816
+ aria-live="${ifDefined(isError ? 'assertive' : undefined)}">
12817
+ ${isError
12818
+ ? this.errorMessage
12819
+ : html$1`<slot name="helpText">${this.getHelpText()}</slot>`
12799
12820
  }
12821
+ </p>
12822
+ </${this.helpTextTag}>
12800
12823
  `;
12801
12824
  }
12802
12825
 
@@ -12943,6 +12966,15 @@ function formatISODate(isoStr, format) {
12943
12966
  try {
12944
12967
  const date = dateFormatter.stringToDateInstance(isoStr);
12945
12968
 
12969
+ // `stringToDateInstance` returns an `Invalid Date` for malformed strings
12970
+ // and `null` for non-string input — it does NOT throw. Without this
12971
+ // guard, `getFullYear()`/`getMonth()`/`getDate()` on an Invalid Date
12972
+ // yield `NaN`, and `String(NaN).padStart(4, '0')` produces literals
12973
+ // like "0NaN/0NaN/0NaN" instead of `undefined`.
12974
+ if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
12975
+ return undefined;
12976
+ }
12977
+
12946
12978
  const year = String(date.getFullYear()).padStart(4, '0');
12947
12979
  const month = String(date.getMonth() + 1).padStart(2, '0');
12948
12980
  const day = String(date.getDate()).padStart(2, '0');
@@ -12953,7 +12985,10 @@ function formatISODate(isoStr, format) {
12953
12985
  replace(/mm/iu, month).
12954
12986
  replace(/dd/iu, day);
12955
12987
  } catch (err) {
12956
- // If the input string is not a valid date, return undefined
12988
+ // Defensive: the Date-returning path is guarded above, but `parseDate`
12989
+ // (inside `stringToDateInstance`) could throw on pathological input
12990
+ // future-library-versions might introduce. Treat any thrown error as
12991
+ // "not a valid date" and return undefined.
12957
12992
  return undefined;
12958
12993
  }
12959
12994
  }