@aurodesignsystem-dev/auro-formkit 0.0.0-pr1507.0 → 0.0.0-pr1508.1

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 (148) hide show
  1. package/components/bibtemplate/dist/index.js +1 -1
  2. package/components/bibtemplate/dist/registered.js +1 -1
  3. package/components/checkbox/demo/customize.html +1 -2
  4. package/components/checkbox/demo/customize.min.js +8 -6
  5. package/components/checkbox/demo/getting-started.min.js +8 -6
  6. package/components/checkbox/demo/index.min.js +8 -6
  7. package/components/checkbox/dist/index.js +8 -6
  8. package/components/checkbox/dist/registered.js +8 -6
  9. package/components/combobox/demo/customize.html +1 -2
  10. package/components/combobox/demo/customize.md +105 -137
  11. package/components/combobox/demo/customize.min.js +506 -568
  12. package/components/combobox/demo/getting-started.min.js +506 -564
  13. package/components/combobox/demo/index.min.js +506 -564
  14. package/components/combobox/demo/keyboard-behavior.md +2 -142
  15. package/components/combobox/demo/why-combobox.md +1 -1
  16. package/components/combobox/dist/auro-combobox.d.ts +30 -14
  17. package/components/combobox/dist/index.js +505 -563
  18. package/components/combobox/dist/registered.js +505 -563
  19. package/components/counter/demo/customize.min.js +26 -8
  20. package/components/counter/demo/index.min.js +26 -8
  21. package/components/counter/dist/index.js +26 -8
  22. package/components/counter/dist/registered.js +26 -8
  23. package/components/datepicker/demo/accessibility.md +2 -1
  24. package/components/datepicker/demo/api.md +65 -62
  25. package/components/datepicker/demo/customize.md +150 -39
  26. package/components/datepicker/demo/customize.min.js +988 -500
  27. package/components/datepicker/demo/index.min.js +988 -482
  28. package/components/datepicker/dist/{src/auro-calendar-cell.d.ts → auro-calendar-cell.d.ts} +20 -3
  29. package/components/datepicker/dist/{src/auro-calendar.d.ts → auro-calendar.d.ts} +121 -7
  30. package/components/datepicker/dist/{src/auro-datepicker.d.ts → auro-datepicker.d.ts} +80 -5
  31. package/components/datepicker/dist/blackoutUtils.d.ts +43 -0
  32. package/components/datepicker/dist/index.js +988 -482
  33. package/components/datepicker/dist/registered.js +988 -482
  34. package/components/dropdown/demo/customize.min.js +10 -1
  35. package/components/dropdown/demo/getting-started.min.js +10 -1
  36. package/components/dropdown/demo/index.min.js +10 -1
  37. package/components/dropdown/dist/auro-dropdown.d.ts +1 -0
  38. package/components/dropdown/dist/index.js +10 -1
  39. package/components/dropdown/dist/registered.js +10 -1
  40. package/components/form/demo/customize.html +6 -6
  41. package/components/form/demo/customize.md +203 -51
  42. package/components/form/demo/customize.min.js +2357 -1419
  43. package/components/form/demo/getting-started.min.js +2285 -1419
  44. package/components/form/demo/index.min.js +2285 -1419
  45. package/components/form/demo/registerDemoDeps.min.js +1922 -1382
  46. package/components/form/dist/auro-form.d.ts +122 -4
  47. package/components/form/dist/index.js +363 -37
  48. package/components/form/dist/registered.js +363 -37
  49. package/components/input/demo/api.md +5 -5
  50. package/components/input/demo/customize.html +1 -2
  51. package/components/input/demo/customize.md +62 -61
  52. package/components/input/demo/customize.min.js +177 -241
  53. package/components/input/demo/getting-started.min.js +177 -241
  54. package/components/input/demo/index.min.js +177 -241
  55. package/components/input/dist/base-input.d.ts +34 -93
  56. package/components/input/dist/index.js +190 -242
  57. package/components/input/dist/registered.js +177 -241
  58. package/components/radio/demo/customize.min.js +8 -6
  59. package/components/radio/demo/getting-started.min.js +8 -6
  60. package/components/radio/demo/index.min.js +8 -6
  61. package/components/radio/dist/index.js +8 -6
  62. package/components/radio/dist/registered.js +8 -6
  63. package/components/select/demo/customize.html +1 -2
  64. package/components/select/demo/customize.md +86 -0
  65. package/components/select/demo/customize.min.js +202 -68
  66. package/components/select/demo/getting-started.min.js +204 -115
  67. package/components/select/demo/index.min.js +202 -68
  68. package/components/select/demo/keyboard-behavior.md +18 -4
  69. package/components/select/dist/auro-select.d.ts +20 -8
  70. package/components/select/dist/index.js +202 -68
  71. package/components/select/dist/registered.js +202 -68
  72. package/custom-elements.json +1035 -604
  73. package/package.json +6 -2
  74. package/components/checkbox/demo/customize.js +0 -22
  75. package/components/checkbox/demo/demo-support.js +0 -1
  76. package/components/checkbox/demo/getting-started.js +0 -22
  77. package/components/checkbox/demo/index.js +0 -8
  78. package/components/checkbox/demo/styles.scss +0 -1
  79. package/components/combobox/demo/customize.js +0 -24
  80. package/components/combobox/demo/demo-support.js +0 -1
  81. package/components/combobox/demo/getting-started.js +0 -21
  82. package/components/combobox/demo/index.js +0 -23
  83. package/components/combobox/demo/styles.scss +0 -1
  84. package/components/counter/demo/customize.js +0 -21
  85. package/components/counter/demo/demo-support.js +0 -1
  86. package/components/counter/demo/index.js +0 -21
  87. package/components/counter/demo/styles.scss +0 -1
  88. package/components/datepicker/demo/customize.js +0 -19
  89. package/components/datepicker/demo/demo-support.js +0 -1
  90. package/components/datepicker/demo/index.js +0 -23
  91. package/components/datepicker/demo/styles.scss +0 -1
  92. package/components/dropdown/demo/customize.js +0 -9
  93. package/components/dropdown/demo/demo-support.js +0 -1
  94. package/components/dropdown/demo/getting-started.js +0 -9
  95. package/components/dropdown/demo/index.js +0 -16
  96. package/components/dropdown/demo/styles.scss +0 -1
  97. package/components/form/demo/customize.js +0 -9
  98. package/components/form/demo/demo-support.js +0 -1
  99. package/components/form/demo/getting-started.js +0 -9
  100. package/components/form/demo/index.js +0 -5
  101. package/components/form/demo/registerDemoDeps.js +0 -23
  102. package/components/form/demo/styles.scss +0 -1
  103. package/components/input/demo/customize.js +0 -25
  104. package/components/input/demo/demo-support.js +0 -1
  105. package/components/input/demo/getting-started.js +0 -8
  106. package/components/input/demo/index.js +0 -8
  107. package/components/input/demo/styles.css +0 -974
  108. package/components/input/demo/styles.scss +0 -1
  109. package/components/menu/demo/demo-support.js +0 -1
  110. package/components/menu/demo/index.js +0 -25
  111. package/components/menu/demo/styles.scss +0 -1
  112. package/components/radio/demo/customize.js +0 -22
  113. package/components/radio/demo/demo-support.js +0 -1
  114. package/components/radio/demo/getting-started.js +0 -24
  115. package/components/radio/demo/index.js +0 -8
  116. package/components/radio/demo/styles.scss +0 -1
  117. package/components/select/demo/customize.js +0 -11
  118. package/components/select/demo/demo-support.js +0 -1
  119. package/components/select/demo/getting-started.js +0 -26
  120. package/components/select/demo/index.js +0 -11
  121. package/components/select/demo/styles.scss +0 -1
  122. /package/components/datepicker/dist/{src/auro-calendar-month.d.ts → auro-calendar-month.d.ts} +0 -0
  123. /package/components/datepicker/dist/{src/buttonVersion.d.ts → buttonVersion.d.ts} +0 -0
  124. /package/components/datepicker/dist/{src/datepickerKeyboardStrategy.d.ts → datepickerKeyboardStrategy.d.ts} +0 -0
  125. /package/components/datepicker/dist/{src/iconVersion.d.ts → iconVersion.d.ts} +0 -0
  126. /package/components/datepicker/dist/{src/index.d.ts → index.d.ts} +0 -0
  127. /package/components/datepicker/dist/{src/popoverVersion.d.ts → popoverVersion.d.ts} +0 -0
  128. /package/components/datepicker/dist/{src/styles → styles}/classic/color-css.d.ts +0 -0
  129. /package/components/datepicker/dist/{src/styles → styles}/classic/style-css.d.ts +0 -0
  130. /package/components/datepicker/dist/{src/styles → styles}/color-calendar-css.d.ts +0 -0
  131. /package/components/datepicker/dist/{src/styles → styles}/color-cell-css.d.ts +0 -0
  132. /package/components/datepicker/dist/{src/styles → styles}/color-css.d.ts +0 -0
  133. /package/components/datepicker/dist/{src/styles → styles}/color-month-css.d.ts +0 -0
  134. /package/components/datepicker/dist/{src/styles → styles}/shapeSize-css.d.ts +0 -0
  135. /package/components/datepicker/dist/{src/styles → styles}/snowflake/color-css.d.ts +0 -0
  136. /package/components/datepicker/dist/{src/styles → styles}/snowflake/style-css.d.ts +0 -0
  137. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-cell-css.d.ts +0 -0
  138. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-css.d.ts +0 -0
  139. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-month-css.d.ts +0 -0
  140. /package/components/datepicker/dist/{src/styles → styles}/style-css.d.ts +0 -0
  141. /package/components/datepicker/dist/{src/styles → styles}/tokens-css.d.ts +0 -0
  142. /package/components/datepicker/dist/{src/utilities.d.ts → utilities.d.ts} +0 -0
  143. /package/components/datepicker/dist/{src/utilitiesCalendar.d.ts → utilitiesCalendar.d.ts} +0 -0
  144. /package/components/datepicker/dist/{src/utilitiesCalendarRender.d.ts → utilitiesCalendarRender.d.ts} +0 -0
  145. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/day.d.ts +0 -0
  146. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker-calendar.d.ts +0 -0
  147. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker-cell.d.ts +0 -0
  148. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker.d.ts +0 -0
@@ -4383,15 +4383,17 @@ class AuroFormValidation {
4383
4383
  );
4384
4384
  }
4385
4385
 
4386
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
4387
- if (this.auroInputElements?.length === 2) {
4388
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
4386
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4387
+
4388
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
4389
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
4390
+ // field (datepicker is the intended consumer — start/end are independently required).
4391
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
4392
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
4389
4393
  hasValue = false;
4390
4394
  }
4391
4395
  }
4392
4396
 
4393
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4394
-
4395
4397
  if (isCombobox) {
4396
4398
 
4397
4399
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -10327,10 +10329,18 @@ class AuroInputUtilities {
10327
10329
  * @returns {string | undefined}
10328
10330
  */
10329
10331
  toFormattedValue(valueObject, format) {
10332
+ // Exposed publicly via `AuroInputUtil.toFormattedValue`, so a missing
10333
+ // `format` argument has to fail gracefully rather than throw on
10334
+ // `format.toLowerCase()`. Treat any falsy value (undefined, null, '')
10335
+ // as "no format → no display value".
10336
+ if (!format) {
10337
+ return undefined;
10338
+ }
10330
10339
  const normalizedFormat = format.toLowerCase();
10331
10340
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10332
10341
 
10333
10342
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10343
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10334
10344
  return undefined;
10335
10345
  }
10336
10346
 
@@ -10477,79 +10487,19 @@ class BaseInput extends AuroElement {
10477
10487
  constructor() {
10478
10488
  super();
10479
10489
 
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() {
10490
+ // Single-source initialization. Alphabetized so duplicate or stale
10491
+ // defaults are immediately obvious on a diff. Every field is assigned
10492
+ // exactly once here (previously the constructor + the old
10493
+ // `_initializePrivateDefaults` overlapped — both wrote ~14 of the same
10494
+ // fields and double-allocated `util` and `validation`, discarding the
10495
+ // first instance). `validation` is now allocated exactly once; `util`
10496
+ // is seeded here with an en-US default and then rebuilt in
10497
+ // `connectedCallback` once the consumer-resolved locale is available,
10498
+ // so a parent (datepicker/combobox) calling `validate()` synchronously
10499
+ // during its own update cycle sees a populated util instance.
10507
10500
  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
10501
 
10502
+ /** @private */
10553
10503
  this.allowedInputTypes = [
10554
10504
  "text",
10555
10505
  "number",
@@ -10558,7 +10508,9 @@ class BaseInput extends AuroElement {
10558
10508
  "credit-card",
10559
10509
  "tel"
10560
10510
  ];
10561
- this.icon = false;
10511
+ this.appearance = "default";
10512
+
10513
+ /** @private */
10562
10514
  this.dateFormatMap = {
10563
10515
  'mm/dd/yyyy': 'dateMMDDYYYY',
10564
10516
  'dd/mm/yyyy': 'dateDDMMYYYY',
@@ -10575,27 +10527,62 @@ class BaseInput extends AuroElement {
10575
10527
  'dd/mm': 'dateDDMM',
10576
10528
  'mm/dd': 'dateMMDD'
10577
10529
  };
10530
+ this.disabled = false;
10531
+
10532
+ /** @private */
10578
10533
  this.domHandler = new DomHandler();
10579
10534
  this.dvInputOnly = false;
10580
10535
  this.hasValue = false;
10536
+ this.hideLabelVisually = false;
10537
+ this.icon = false;
10538
+
10539
+ /** @private */
10581
10540
  this.inputIconName = undefined;
10541
+
10542
+ /** @private */
10582
10543
  this.label = 'Input label is undefined';
10544
+ this.layout = 'classic';
10545
+ this.locale = 'en-US';
10546
+ this.max = undefined;
10547
+ this.maxLength = undefined;
10548
+ this.min = undefined;
10549
+ this.minLength = undefined;
10583
10550
  this.noValidate = false;
10584
- this._rawMaskValue = undefined; // Used for storing raw values returned from input mask.
10551
+ this.onDark = false;
10552
+ // Raw values returned from the input mask before model normalization.
10553
+ this._rawMaskValue = undefined;
10554
+ this.required = false;
10555
+ this.setCustomValidityForType = undefined;
10556
+ // Credit Card is intentionally excluded — its mask manages the cursor
10557
+ // itself, and listing it here caused cursor placement issues in Safari.
10558
+ /** @private */
10585
10559
  this.setSelectionInputTypes = [
10586
10560
  "text",
10587
10561
  "password",
10588
10562
  "email"
10589
- ]; // Credit Card is not included as this caused cursor placement issues in Safari.
10563
+ ];
10564
+ this.shape = 'classic';
10565
+
10566
+ /** @private */
10590
10567
  this.showPassword = false;
10568
+ this.size = 'lg';
10591
10569
  this.touched = false;
10570
+
10571
+ /** @private */
10592
10572
  this.uniqueId = new UniqueId().create();
10573
+
10574
+ /** @private */
10593
10575
  this.util = new AuroInputUtilities({
10594
10576
  locale: this.locale,
10595
10577
  format: this.format
10596
10578
  });
10579
+
10580
+ /** @private */
10597
10581
  this.validation = new AuroFormValidation();
10582
+
10583
+ /** @private */
10598
10584
  this.validationCCLength = undefined;
10585
+ this.value = undefined;
10599
10586
  }
10600
10587
 
10601
10588
  // function to define props used within the scope of this component
@@ -11033,7 +11020,7 @@ class BaseInput extends AuroElement {
11033
11020
  * @returns {Date|undefined}
11034
11021
  */
11035
11022
  get valueObject() {
11036
- return this._valueObject || this._computeDateObjectFallback(this.value);
11023
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
11037
11024
  }
11038
11025
 
11039
11026
  /**
@@ -11041,7 +11028,7 @@ class BaseInput extends AuroElement {
11041
11028
  * @returns {Date|undefined}
11042
11029
  */
11043
11030
  get minObject() {
11044
- return this._minObject || this._computeDateObjectFallback(this.min);
11031
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
11045
11032
  }
11046
11033
 
11047
11034
  /**
@@ -11049,50 +11036,7 @@ class BaseInput extends AuroElement {
11049
11036
  * @returns {Date|undefined}
11050
11037
  */
11051
11038
  get maxObject() {
11052
- return this._maxObject || this._computeDateObjectFallback(this.max);
11053
- }
11054
-
11055
- /**
11056
- * Parses a date string into a Date object when the corresponding `_*Object`
11057
- * field hasn't been synced yet by `updated()`. Returns undefined when the
11058
- * input type/format isn't a full date or the string is not a valid date.
11059
- *
11060
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
11061
- * inside its own `updated()` before this input's `updated()` has run
11062
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
11063
- * and range checks would otherwise silently no-op (flipping the result to
11064
- * `valid` or `patternMismatch`).
11065
- * @private
11066
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
11067
- * @returns {Date|undefined}
11068
- */
11069
- _computeDateObjectFallback(dateStr) {
11070
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
11071
- return undefined;
11072
- }
11073
- if (!dateFormatter.isValidDate(dateStr)) {
11074
- return undefined;
11075
- }
11076
- return dateFormatter.stringToDateInstance(dateStr);
11077
- }
11078
-
11079
- /**
11080
- * Internal setter for readonly date object properties.
11081
- * @private
11082
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
11083
- * @param {Date|undefined} propertyValue - Value to assign.
11084
- * @returns {void}
11085
- */
11086
- setDateObjectProperty(propertyName, propertyValue) {
11087
- const internalPropertyName = `_${propertyName}`;
11088
- const previousValue = this[internalPropertyName];
11089
-
11090
- if (previousValue === propertyValue) {
11091
- return;
11092
- }
11093
-
11094
- this[internalPropertyName] = propertyValue;
11095
- this.requestUpdate(propertyName, previousValue);
11039
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
11096
11040
  }
11097
11041
 
11098
11042
  connectedCallback() {
@@ -11121,7 +11065,6 @@ class BaseInput extends AuroElement {
11121
11065
  format: this.format
11122
11066
  });
11123
11067
  this.configureDataForType();
11124
- this.syncDateValues();
11125
11068
  }
11126
11069
 
11127
11070
  disconnectedCallback() {
@@ -11141,12 +11084,17 @@ class BaseInput extends AuroElement {
11141
11084
  this.wrapperElement.addEventListener('click', this.handleClick);
11142
11085
  }
11143
11086
 
11144
- // add attribute for query selectors when auro-input is registered under a custom name
11145
- if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
11146
- this.setAttribute('auro-input', '');
11147
- }
11148
11087
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
11149
11088
 
11089
+ // Normalize the format token to lowercase so case-mixed values supplied
11090
+ // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
11091
+ // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
11092
+ // format silently misses the map and leaves `setCustomValidityForType`
11093
+ // unset.
11094
+ if (this.format) {
11095
+ this.format = this.format.toLowerCase();
11096
+ }
11097
+
11150
11098
  // use validity message override if declared when initializing the component
11151
11099
  if (this.hasAttribute('setCustomValidity')) {
11152
11100
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -11155,7 +11103,6 @@ class BaseInput extends AuroElement {
11155
11103
  this.setCustomHelpTextMessage();
11156
11104
  this.configureAutoFormatting();
11157
11105
  this.configureDataForType();
11158
- this.syncDateValues();
11159
11106
  }
11160
11107
 
11161
11108
  /**
@@ -11231,6 +11178,13 @@ class BaseInput extends AuroElement {
11231
11178
 
11232
11179
  if (typeToI18n.includes(this.type)) {
11233
11180
  this.setCustomValidityForType = i18n(this.lang, this.type);
11181
+ // COVERAGE: this `else if` branch is unreachable in WTR. connectedCallback
11182
+ // (L682) calls configureDataForType, which at L1266-1268 assigns
11183
+ // `this.format = this.util.getDateMaskFromLocale().toLowerCase()` for any
11184
+ // type=date input whose `format` attribute is unset. That runs before
11185
+ // firstUpdated invokes setCustomHelpTextMessage, so `!this.format` is
11186
+ // always false here. Retained as a defensive fallback; the whole function
11187
+ // is @deprecated per AB#1557296 and slated for removal.
11234
11188
  } else if (!this.format && this.type === 'date') {
11235
11189
  this.setCustomValidityForType = i18n(this.lang, 'dateMMDDYYYY');
11236
11190
  } else if (this.dateFormatMap[this.format]) {
@@ -11292,8 +11246,6 @@ class BaseInput extends AuroElement {
11292
11246
  this.configureDataForType();
11293
11247
  }
11294
11248
 
11295
- this.syncDateValues(changedProperties);
11296
-
11297
11249
  if (changedProperties.has('value')) {
11298
11250
  if (this.value && this.value.length > 0) {
11299
11251
  this.hasValue = true;
@@ -11315,14 +11267,14 @@ class BaseInput extends AuroElement {
11315
11267
 
11316
11268
  if (formattedValue !== this.inputElement.value) {
11317
11269
  this.skipNextProgrammaticInputEvent = true;
11318
- if (this.maskInstance && this.type === 'credit-card') {
11270
+ if (this.maskInstance && this.type !== 'date') {
11319
11271
  // Route through the mask so its _value and el.value stay in lock-step
11320
11272
  // (set value calls updateControl which writes el.value = displayValue).
11321
11273
  // Writing el.value directly leaves the mask thinking displayValue is
11322
- // stale; _saveSelection on the next focus/click then warns. Scoped to
11323
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11324
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11325
- // and flip validity from patternMismatch to tooShort.
11274
+ // stale; _saveSelection on the next focus/click then warns. Date is
11275
+ // excluded because its formattedValue can be raw ISO when the calendar
11276
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11277
+ // flip validity from patternMismatch to tooShort.
11326
11278
  this.maskInstance.value = formattedValue || '';
11327
11279
  } else if (formattedValue) {
11328
11280
  this.inputElement.value = formattedValue;
@@ -11364,120 +11316,65 @@ class BaseInput extends AuroElement {
11364
11316
  }));
11365
11317
  }
11366
11318
 
11367
-
11368
- /**
11369
- * Synchronizes the ISO string values and Date object representations for date-related properties.
11370
- * This keeps the model and display values aligned when either side changes.
11371
- *
11372
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11373
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11374
- * represents a full year/month/day date format.
11375
- *
11376
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11377
- * @returns {void}
11378
- * @private
11379
- */
11380
- syncDateValues(changedProperties = undefined) {
11381
- if (!this.util.isFullDateFormat(this.type, this.format)) {
11382
- return;
11383
- }
11384
-
11385
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11386
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11387
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11388
- }
11389
-
11390
- /**
11391
- * Synchronizes one date object/string property pair.
11392
- * @private
11393
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11394
- * @param {string} objectProperty - Date object property name.
11395
- * @param {string} valueProperty - ISO string property name.
11396
- * @returns {void}
11397
- */
11398
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11399
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11400
-
11401
- // objectProperty wins over valueProperty when both changed
11402
- if (objectPropertyChanged && this[objectProperty]) {
11403
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
11404
- return;
11405
- }
11406
-
11407
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11408
- if (!valuePropertyChanged) {
11409
- return;
11410
- }
11411
-
11412
- // when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
11413
- if (
11414
- changedProperties &&
11415
- valueProperty === 'value' &&
11416
- changedProperties.get('value') === undefined &&
11417
- this[objectProperty] instanceof Date &&
11418
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
11419
- ) {
11420
- return;
11421
- }
11422
-
11423
- if (dateFormatter.isValidDate(this[valueProperty])) {
11424
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
11425
- } else {
11426
- this.setDateObjectProperty(objectProperty, undefined);
11427
- }
11428
- }
11429
-
11430
11319
  /**
11431
11320
  * Sets up IMasks and logic based on auto-formatting requirements.
11432
11321
  * @private
11433
11322
  * @returns {void}
11434
11323
  */
11435
11324
  configureAutoFormatting() {
11436
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11437
- // by _configuringMask above) could otherwise trigger handleInput
11438
- // processCreditCard configureAutoFormatting before the outer call's
11439
- // set value has finished its alignCursor pass.
11325
+ // _configuringMask gates two things: external re-entry into this method
11326
+ // while setup is mid-flight (from property changes that call back here),
11327
+ // and the accept/complete listeners below — both need to ignore the mask
11328
+ // events fired by our own value-restore step.
11440
11329
  if (this._configuringMask) return;
11441
11330
  this._configuringMask = true;
11442
11331
  try {
11332
+ // Destroy any prior mask so IMask can attach fresh under the new format.
11333
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11334
+ // type switched from credit-card to text) the IMask() reassignment
11335
+ // below is skipped, and downstream writes at line ~823 would otherwise
11336
+ // route through the destroyed instance.
11443
11337
  if (this.maskInstance) {
11444
11338
  this.maskInstance.destroy();
11339
+ this.maskInstance = null;
11445
11340
  }
11446
11341
 
11447
- // Pass new format to util
11448
11342
  this.util.updateFormat(this.format);
11449
11343
 
11450
11344
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11451
11345
 
11452
11346
  if (this.inputElement && maskOptions.mask) {
11453
-
11454
- // Stash and clear any existing value before IMask init.
11455
- // IMask's constructor processes the current input value which requires
11456
- // selection state clearing first avoids that scenario entirely.
11457
- // When the format changes (e.g. locale switch) and we have a valid ISO
11458
- // model value, compute the display string for the NEW format instead of
11459
- // re-using the old display string, which may be invalid in the new mask.
11347
+ // Capture the current display so it can be re-applied after IMask
11348
+ // attaches. The restore at the bottom goes through maskInstance.value
11349
+ // (not inputElement.value directly) so the mask's internal state and
11350
+ // the input's displayed text stay in lock-step.
11460
11351
  let existingValue = this.inputElement.value;
11352
+
11353
+ // Format-change case (e.g. locale switch): existingValue is the OLD
11354
+ // mask's display string and may not parse under the new mask. When
11355
+ // we have a valid date model, rebuild the display from valueObject
11356
+ // (the canonical source) using the new mask's format function.
11461
11357
  if (
11462
11358
  this.util.isFullDateFormat(this.type, this.format) &&
11463
11359
  this.value &&
11464
- dateFormatter.isValidDate(this.value) &&
11465
- this.valueObject instanceof Date &&
11466
- !Number.isNaN(this.valueObject.getTime()) &&
11360
+ this.valueObject &&
11467
11361
  typeof maskOptions.format === 'function'
11468
11362
  ) {
11469
11363
  existingValue = maskOptions.format(this.valueObject);
11470
11364
  }
11471
11365
 
11366
+ // Clear before IMask attaches so the constructor seeds an empty
11367
+ // internal value. Otherwise IMask reads the stale unmasked string
11368
+ // and emits a spurious 'accept' before the restore below runs.
11472
11369
  this.skipNextProgrammaticInputEvent = true;
11473
11370
  this.inputElement.value = '';
11474
11371
 
11475
11372
  this.maskInstance = IMask(this.inputElement, maskOptions);
11476
11373
 
11374
+ // Mask fires 'accept' on every value change, including the restore
11375
+ // step below. Skip events fired during configureAutoFormatting so
11376
+ // we don't overwrite a value the parent just pushed.
11477
11377
  this.maskInstance.on('accept', () => {
11478
- // Suppress propagation during configureAutoFormatting's own value-restoration
11479
- // (line below) — the mask emits 'accept' on every value-set, including ours,
11480
- // and we don't want to overwrite a value the parent just pushed.
11481
11378
  if (this._configuringMask) return;
11482
11379
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11483
11380
  if (this.type === "date") {
@@ -11485,6 +11382,8 @@ class BaseInput extends AuroElement {
11485
11382
  }
11486
11383
  });
11487
11384
 
11385
+ // Mask fires 'complete' on the restore step below for any value that
11386
+ // happens to be a complete match. Same setup-suppression as 'accept'.
11488
11387
  this.maskInstance.on('complete', () => {
11489
11388
  if (this._configuringMask) return;
11490
11389
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11493,7 +11392,9 @@ class BaseInput extends AuroElement {
11493
11392
  }
11494
11393
  });
11495
11394
 
11496
- // Restore the stashed value through IMask so it's properly masked
11395
+ // Write existingValue through the mask (not the input directly) so
11396
+ // the mask reformats it under the new rules and keeps its internal
11397
+ // _value aligned with the input's displayed text.
11497
11398
  if (existingValue) {
11498
11399
  this.maskInstance.value = existingValue;
11499
11400
  }
@@ -11573,6 +11474,38 @@ class BaseInput extends AuroElement {
11573
11474
  this.touched = true;
11574
11475
  this.validation.validate(this);
11575
11476
  }
11477
+
11478
+ // Prevents cursor jumping in Safari. Setting `this.value` triggers a Lit
11479
+ // update that can re-render the input and reset the native cursor; we
11480
+ // capture the caret position before that update commits and restore it
11481
+ // via `setSelectionRange` once the update has flushed. Gated on
11482
+ // `setSelectionInputTypes` so credit-card (and other masked types whose
11483
+ // formatter manages the cursor itself) doesn't get a competing write.
11484
+ // Capture the caret position INSIDE the gate — reading `selectionStart`
11485
+ // on input types that don't support text selection (number, email in
11486
+ // some browsers) throws InvalidStateError, which would crash all input
11487
+ // handling. Wrap the read in try/catch belt-and-suspenders even though
11488
+ // the gated types currently support it, since the list is a public
11489
+ // property a consumer could mutate.
11490
+ if (this.setSelectionInputTypes.includes(this.type)) {
11491
+ let selectionStart = null;
11492
+ try {
11493
+ ({ selectionStart } = this.inputElement);
11494
+ } catch (error) { // eslint-disable-line no-unused-vars
11495
+ return;
11496
+ }
11497
+ if (typeof selectionStart !== 'number') {
11498
+ return;
11499
+ }
11500
+ this.updateComplete.then(() => {
11501
+ try {
11502
+ this.inputElement.setSelectionRange(selectionStart, selectionStart);
11503
+ } catch (error) { // eslint-disable-line no-unused-vars
11504
+ // Some input types (number/email in certain UAs) throw on
11505
+ // setSelectionRange; swallow and let the native cursor stand.
11506
+ }
11507
+ });
11508
+ }
11576
11509
  }
11577
11510
 
11578
11511
  /**
@@ -11661,7 +11594,6 @@ class BaseInput extends AuroElement {
11661
11594
  */
11662
11595
  reset() {
11663
11596
  this.value = undefined;
11664
- this.setDateObjectProperty('valueObject', undefined);
11665
11597
  this.validation.reset(this);
11666
11598
  }
11667
11599
 
@@ -11670,7 +11602,6 @@ class BaseInput extends AuroElement {
11670
11602
  */
11671
11603
  clear() {
11672
11604
  this.value = undefined;
11673
- this.setDateObjectProperty('valueObject', undefined);
11674
11605
  }
11675
11606
 
11676
11607
  /**
@@ -11708,7 +11639,7 @@ class BaseInput extends AuroElement {
11708
11639
  */
11709
11640
  get placeholderStr() {
11710
11641
  if (!this.placeholder && this.type === 'date') {
11711
- return this.format ? this.format.toUpperCase() : 'MM/DD/YYYY';
11642
+ return this.format.toUpperCase();
11712
11643
  }
11713
11644
  return this.placeholder || "";
11714
11645
  }
@@ -12199,7 +12130,7 @@ class AuroHelpText extends LitElement {
12199
12130
  }
12200
12131
  }
12201
12132
 
12202
- var formkitVersion = '202606192121';
12133
+ var formkitVersion = '202607010100';
12203
12134
 
12204
12135
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12205
12136
  // See LICENSE in the project root for license information.
@@ -12702,6 +12633,7 @@ class AuroInput extends BaseInput {
12702
12633
  <${this.buttonTag}
12703
12634
  @click="${this.handleClickShowPassword}"
12704
12635
  appearance="${this.onDark ? 'inverse' : this.appearance}"
12636
+ aria-pressed="${this.showPassword ? 'true' : 'false'}"
12705
12637
  class="notificationBtn passwordBtn"
12706
12638
  shape="circle"
12707
12639
  size="sm"
@@ -12775,25 +12707,29 @@ class AuroInput extends BaseInput {
12775
12707
  * @returns {html} - Returns HTML for the help text and error message.
12776
12708
  */
12777
12709
  renderHtmlHelpText() {
12710
+ // Single `<p>` with stable identity across validity transitions —
12711
+ // previously two distinct templates (valid vs invalid) caused Lit to
12712
+ // replace the node entirely on a flip, and VoiceOver wouldn't
12713
+ // re-announce because the live-region element it was watching had been
12714
+ // removed and a new one inserted. Keeping one node means the `role`,
12715
+ // `aria-live`, and text content all change in-place, which AT does
12716
+ // observe and announce.
12717
+ const isError = this.validity && this.validity !== 'valid';
12778
12718
  return html$1`
12779
- ${!this.validity || this.validity === undefined || this.validity === 'valid'
12780
- ? html$1`
12781
- <${this.helpTextTag}
12782
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12783
- <p id="${this.uniqueId}" part="helpText">
12784
- <slot name="helpText">${this.getHelpText()}</slot>
12785
- </p>
12786
- </${this.helpTextTag}>
12787
- `
12788
- : html$1`
12789
- <${this.helpTextTag} error
12790
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12791
- <p id="${this.uniqueId}" role="alert" aria-live="assertive" part="helpText">
12792
- ${this.errorMessage}
12793
- </p>
12794
- </${this.helpTextTag}>
12795
- `
12719
+ <${this.helpTextTag}
12720
+ appearance="${this.onDark ? 'inverse' : this.appearance}"
12721
+ ?error=${isError}>
12722
+ <p
12723
+ id="${this.uniqueId}"
12724
+ part="helpText"
12725
+ role="${ifDefined(isError ? 'alert' : undefined)}"
12726
+ aria-live="${ifDefined(isError ? 'assertive' : undefined)}">
12727
+ ${isError
12728
+ ? this.errorMessage
12729
+ : html$1`<slot name="helpText">${this.getHelpText()}</slot>`
12796
12730
  }
12731
+ </p>
12732
+ </${this.helpTextTag}>
12797
12733
  `;
12798
12734
  }
12799
12735