@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
@@ -4441,15 +4441,17 @@ class AuroFormValidation {
4441
4441
  );
4442
4442
  }
4443
4443
 
4444
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
4445
- if (this.auroInputElements?.length === 2) {
4446
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
4444
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4445
+
4446
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
4447
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
4448
+ // field (datepicker is the intended consumer — start/end are independently required).
4449
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
4450
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
4447
4451
  hasValue = false;
4448
4452
  }
4449
4453
  }
4450
4454
 
4451
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4452
-
4453
4455
  if (isCombobox) {
4454
4456
 
4455
4457
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -10385,10 +10387,18 @@ class AuroInputUtilities {
10385
10387
  * @returns {string | undefined}
10386
10388
  */
10387
10389
  toFormattedValue(valueObject, format) {
10390
+ // Exposed publicly via `AuroInputUtil.toFormattedValue`, so a missing
10391
+ // `format` argument has to fail gracefully rather than throw on
10392
+ // `format.toLowerCase()`. Treat any falsy value (undefined, null, '')
10393
+ // as "no format → no display value".
10394
+ if (!format) {
10395
+ return undefined;
10396
+ }
10388
10397
  const normalizedFormat = format.toLowerCase();
10389
10398
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10390
10399
 
10391
10400
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10401
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10392
10402
  return undefined;
10393
10403
  }
10394
10404
 
@@ -10535,79 +10545,19 @@ class BaseInput extends AuroElement {
10535
10545
  constructor() {
10536
10546
  super();
10537
10547
 
10538
- this.appearance = "default";
10539
- this.disabled = false;
10540
- this.layout = 'classic';
10541
- this.locale = 'en-US';
10542
- this.max = undefined;
10543
- this._maxObject = undefined;
10544
- this.maxLength = undefined;
10545
- this.min = undefined;
10546
- this._minObject = undefined;
10547
- this.minLength = undefined;
10548
- this.required = false;
10549
- this.onDark = false;
10550
- this.setCustomValidityForType = undefined;
10551
- this.size = 'lg';
10552
- this.shape = 'classic';
10553
- this.value = undefined;
10554
- this._valueObject = undefined;
10555
-
10556
- this._initializePrivateDefaults();
10557
- }
10558
-
10559
- /**
10560
- * Internal Defaults.
10561
- * @private
10562
- * @returns {void}
10563
- */
10564
- _initializePrivateDefaults() {
10548
+ // Single-source initialization. Alphabetized so duplicate or stale
10549
+ // defaults are immediately obvious on a diff. Every field is assigned
10550
+ // exactly once here (previously the constructor + the old
10551
+ // `_initializePrivateDefaults` overlapped — both wrote ~14 of the same
10552
+ // fields and double-allocated `util` and `validation`, discarding the
10553
+ // first instance). `validation` is now allocated exactly once; `util`
10554
+ // is seeded here with an en-US default and then rebuilt in
10555
+ // `connectedCallback` once the consumer-resolved locale is available,
10556
+ // so a parent (datepicker/combobox) calling `validate()` synchronously
10557
+ // during its own update cycle sees a populated util instance.
10565
10558
  this.activeLabel = false;
10566
- this.appearance = "default";
10567
- this.icon = false;
10568
- this.disabled = false;
10569
- this.dvInputOnly = false;
10570
- this.hideLabelVisually = false;
10571
- this.max = undefined;
10572
- this.maxLength = undefined;
10573
- this.min = undefined;
10574
- this.minLength = undefined;
10575
- this.noValidate = false;
10576
- this.onDark = false;
10577
- this.required = false;
10578
- this.setCustomValidityForType = undefined;
10579
-
10580
- // Used for storing raw values returned from input mask.
10581
- this._rawMaskValue = undefined;
10582
-
10583
- /**
10584
- * @private
10585
- */
10586
- this.layout = 'classic';
10587
-
10588
- /**
10589
- * @private
10590
- */
10591
- this.shape = 'classic';
10592
-
10593
- /**
10594
- * @private
10595
- */
10596
- this.size = 'lg';
10597
-
10598
- this.touched = false;
10599
- this.util = new AuroInputUtilities({
10600
- locale: "en-US",
10601
- format: this.format
10602
- });
10603
- this.validation = new AuroFormValidation();
10604
- this.inputIconName = undefined;
10605
- this.showPassword = false;
10606
- this.validationCCLength = undefined;
10607
- this.hasValue = false;
10608
- this.label = 'Input label is undefined';
10609
-
10610
10559
 
10560
+ /** @private */
10611
10561
  this.allowedInputTypes = [
10612
10562
  "text",
10613
10563
  "number",
@@ -10616,7 +10566,9 @@ class BaseInput extends AuroElement {
10616
10566
  "credit-card",
10617
10567
  "tel"
10618
10568
  ];
10619
- this.icon = false;
10569
+ this.appearance = "default";
10570
+
10571
+ /** @private */
10620
10572
  this.dateFormatMap = {
10621
10573
  'mm/dd/yyyy': 'dateMMDDYYYY',
10622
10574
  'dd/mm/yyyy': 'dateDDMMYYYY',
@@ -10633,27 +10585,62 @@ class BaseInput extends AuroElement {
10633
10585
  'dd/mm': 'dateDDMM',
10634
10586
  'mm/dd': 'dateMMDD'
10635
10587
  };
10588
+ this.disabled = false;
10589
+
10590
+ /** @private */
10636
10591
  this.domHandler = new DomHandler();
10637
10592
  this.dvInputOnly = false;
10638
10593
  this.hasValue = false;
10594
+ this.hideLabelVisually = false;
10595
+ this.icon = false;
10596
+
10597
+ /** @private */
10639
10598
  this.inputIconName = undefined;
10599
+
10600
+ /** @private */
10640
10601
  this.label = 'Input label is undefined';
10602
+ this.layout = 'classic';
10603
+ this.locale = 'en-US';
10604
+ this.max = undefined;
10605
+ this.maxLength = undefined;
10606
+ this.min = undefined;
10607
+ this.minLength = undefined;
10641
10608
  this.noValidate = false;
10642
- this._rawMaskValue = undefined; // Used for storing raw values returned from input mask.
10609
+ this.onDark = false;
10610
+ // Raw values returned from the input mask before model normalization.
10611
+ this._rawMaskValue = undefined;
10612
+ this.required = false;
10613
+ this.setCustomValidityForType = undefined;
10614
+ // Credit Card is intentionally excluded — its mask manages the cursor
10615
+ // itself, and listing it here caused cursor placement issues in Safari.
10616
+ /** @private */
10643
10617
  this.setSelectionInputTypes = [
10644
10618
  "text",
10645
10619
  "password",
10646
10620
  "email"
10647
- ]; // Credit Card is not included as this caused cursor placement issues in Safari.
10621
+ ];
10622
+ this.shape = 'classic';
10623
+
10624
+ /** @private */
10648
10625
  this.showPassword = false;
10626
+ this.size = 'lg';
10649
10627
  this.touched = false;
10628
+
10629
+ /** @private */
10650
10630
  this.uniqueId = new UniqueId().create();
10631
+
10632
+ /** @private */
10651
10633
  this.util = new AuroInputUtilities({
10652
10634
  locale: this.locale,
10653
10635
  format: this.format
10654
10636
  });
10637
+
10638
+ /** @private */
10655
10639
  this.validation = new AuroFormValidation();
10640
+
10641
+ /** @private */
10656
10642
  this.validationCCLength = undefined;
10643
+ this.value = undefined;
10657
10644
  }
10658
10645
 
10659
10646
  // function to define props used within the scope of this component
@@ -11091,7 +11078,7 @@ class BaseInput extends AuroElement {
11091
11078
  * @returns {Date|undefined}
11092
11079
  */
11093
11080
  get valueObject() {
11094
- return this._valueObject || this._computeDateObjectFallback(this.value);
11081
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
11095
11082
  }
11096
11083
 
11097
11084
  /**
@@ -11099,7 +11086,7 @@ class BaseInput extends AuroElement {
11099
11086
  * @returns {Date|undefined}
11100
11087
  */
11101
11088
  get minObject() {
11102
- return this._minObject || this._computeDateObjectFallback(this.min);
11089
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
11103
11090
  }
11104
11091
 
11105
11092
  /**
@@ -11107,50 +11094,7 @@ class BaseInput extends AuroElement {
11107
11094
  * @returns {Date|undefined}
11108
11095
  */
11109
11096
  get maxObject() {
11110
- return this._maxObject || this._computeDateObjectFallback(this.max);
11111
- }
11112
-
11113
- /**
11114
- * Parses a date string into a Date object when the corresponding `_*Object`
11115
- * field hasn't been synced yet by `updated()`. Returns undefined when the
11116
- * input type/format isn't a full date or the string is not a valid date.
11117
- *
11118
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
11119
- * inside its own `updated()` before this input's `updated()` has run
11120
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
11121
- * and range checks would otherwise silently no-op (flipping the result to
11122
- * `valid` or `patternMismatch`).
11123
- * @private
11124
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
11125
- * @returns {Date|undefined}
11126
- */
11127
- _computeDateObjectFallback(dateStr) {
11128
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
11129
- return undefined;
11130
- }
11131
- if (!dateFormatter.isValidDate(dateStr)) {
11132
- return undefined;
11133
- }
11134
- return dateFormatter.stringToDateInstance(dateStr);
11135
- }
11136
-
11137
- /**
11138
- * Internal setter for readonly date object properties.
11139
- * @private
11140
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
11141
- * @param {Date|undefined} propertyValue - Value to assign.
11142
- * @returns {void}
11143
- */
11144
- setDateObjectProperty(propertyName, propertyValue) {
11145
- const internalPropertyName = `_${propertyName}`;
11146
- const previousValue = this[internalPropertyName];
11147
-
11148
- if (previousValue === propertyValue) {
11149
- return;
11150
- }
11151
-
11152
- this[internalPropertyName] = propertyValue;
11153
- this.requestUpdate(propertyName, previousValue);
11097
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
11154
11098
  }
11155
11099
 
11156
11100
  connectedCallback() {
@@ -11179,7 +11123,6 @@ class BaseInput extends AuroElement {
11179
11123
  format: this.format
11180
11124
  });
11181
11125
  this.configureDataForType();
11182
- this.syncDateValues();
11183
11126
  }
11184
11127
 
11185
11128
  disconnectedCallback() {
@@ -11199,12 +11142,17 @@ class BaseInput extends AuroElement {
11199
11142
  this.wrapperElement.addEventListener('click', this.handleClick);
11200
11143
  }
11201
11144
 
11202
- // add attribute for query selectors when auro-input is registered under a custom name
11203
- if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
11204
- this.setAttribute('auro-input', '');
11205
- }
11206
11145
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
11207
11146
 
11147
+ // Normalize the format token to lowercase so case-mixed values supplied
11148
+ // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
11149
+ // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
11150
+ // format silently misses the map and leaves `setCustomValidityForType`
11151
+ // unset.
11152
+ if (this.format) {
11153
+ this.format = this.format.toLowerCase();
11154
+ }
11155
+
11208
11156
  // use validity message override if declared when initializing the component
11209
11157
  if (this.hasAttribute('setCustomValidity')) {
11210
11158
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -11213,7 +11161,6 @@ class BaseInput extends AuroElement {
11213
11161
  this.setCustomHelpTextMessage();
11214
11162
  this.configureAutoFormatting();
11215
11163
  this.configureDataForType();
11216
- this.syncDateValues();
11217
11164
  }
11218
11165
 
11219
11166
  /**
@@ -11289,6 +11236,13 @@ class BaseInput extends AuroElement {
11289
11236
 
11290
11237
  if (typeToI18n.includes(this.type)) {
11291
11238
  this.setCustomValidityForType = i18n(this.lang, this.type);
11239
+ // COVERAGE: this `else if` branch is unreachable in WTR. connectedCallback
11240
+ // (L682) calls configureDataForType, which at L1266-1268 assigns
11241
+ // `this.format = this.util.getDateMaskFromLocale().toLowerCase()` for any
11242
+ // type=date input whose `format` attribute is unset. That runs before
11243
+ // firstUpdated invokes setCustomHelpTextMessage, so `!this.format` is
11244
+ // always false here. Retained as a defensive fallback; the whole function
11245
+ // is @deprecated per AB#1557296 and slated for removal.
11292
11246
  } else if (!this.format && this.type === 'date') {
11293
11247
  this.setCustomValidityForType = i18n(this.lang, 'dateMMDDYYYY');
11294
11248
  } else if (this.dateFormatMap[this.format]) {
@@ -11350,8 +11304,6 @@ class BaseInput extends AuroElement {
11350
11304
  this.configureDataForType();
11351
11305
  }
11352
11306
 
11353
- this.syncDateValues(changedProperties);
11354
-
11355
11307
  if (changedProperties.has('value')) {
11356
11308
  if (this.value && this.value.length > 0) {
11357
11309
  this.hasValue = true;
@@ -11373,14 +11325,14 @@ class BaseInput extends AuroElement {
11373
11325
 
11374
11326
  if (formattedValue !== this.inputElement.value) {
11375
11327
  this.skipNextProgrammaticInputEvent = true;
11376
- if (this.maskInstance && this.type === 'credit-card') {
11328
+ if (this.maskInstance && this.type !== 'date') {
11377
11329
  // Route through the mask so its _value and el.value stay in lock-step
11378
11330
  // (set value calls updateControl which writes el.value = displayValue).
11379
11331
  // Writing el.value directly leaves the mask thinking displayValue is
11380
- // stale; _saveSelection on the next focus/click then warns. Scoped to
11381
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11382
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11383
- // and flip validity from patternMismatch to tooShort.
11332
+ // stale; _saveSelection on the next focus/click then warns. Date is
11333
+ // excluded because its formattedValue can be raw ISO when the calendar
11334
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11335
+ // flip validity from patternMismatch to tooShort.
11384
11336
  this.maskInstance.value = formattedValue || '';
11385
11337
  } else if (formattedValue) {
11386
11338
  this.inputElement.value = formattedValue;
@@ -11422,120 +11374,65 @@ class BaseInput extends AuroElement {
11422
11374
  }));
11423
11375
  }
11424
11376
 
11425
-
11426
- /**
11427
- * Synchronizes the ISO string values and Date object representations for date-related properties.
11428
- * This keeps the model and display values aligned when either side changes.
11429
- *
11430
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11431
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11432
- * represents a full year/month/day date format.
11433
- *
11434
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11435
- * @returns {void}
11436
- * @private
11437
- */
11438
- syncDateValues(changedProperties = undefined) {
11439
- if (!this.util.isFullDateFormat(this.type, this.format)) {
11440
- return;
11441
- }
11442
-
11443
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11444
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11445
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11446
- }
11447
-
11448
- /**
11449
- * Synchronizes one date object/string property pair.
11450
- * @private
11451
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11452
- * @param {string} objectProperty - Date object property name.
11453
- * @param {string} valueProperty - ISO string property name.
11454
- * @returns {void}
11455
- */
11456
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11457
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11458
-
11459
- // objectProperty wins over valueProperty when both changed
11460
- if (objectPropertyChanged && this[objectProperty]) {
11461
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
11462
- return;
11463
- }
11464
-
11465
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11466
- if (!valuePropertyChanged) {
11467
- return;
11468
- }
11469
-
11470
- // 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)
11471
- if (
11472
- changedProperties &&
11473
- valueProperty === 'value' &&
11474
- changedProperties.get('value') === undefined &&
11475
- this[objectProperty] instanceof Date &&
11476
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
11477
- ) {
11478
- return;
11479
- }
11480
-
11481
- if (dateFormatter.isValidDate(this[valueProperty])) {
11482
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
11483
- } else {
11484
- this.setDateObjectProperty(objectProperty, undefined);
11485
- }
11486
- }
11487
-
11488
11377
  /**
11489
11378
  * Sets up IMasks and logic based on auto-formatting requirements.
11490
11379
  * @private
11491
11380
  * @returns {void}
11492
11381
  */
11493
11382
  configureAutoFormatting() {
11494
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11495
- // by _configuringMask above) could otherwise trigger handleInput
11496
- // processCreditCard configureAutoFormatting before the outer call's
11497
- // set value has finished its alignCursor pass.
11383
+ // _configuringMask gates two things: external re-entry into this method
11384
+ // while setup is mid-flight (from property changes that call back here),
11385
+ // and the accept/complete listeners below — both need to ignore the mask
11386
+ // events fired by our own value-restore step.
11498
11387
  if (this._configuringMask) return;
11499
11388
  this._configuringMask = true;
11500
11389
  try {
11390
+ // Destroy any prior mask so IMask can attach fresh under the new format.
11391
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11392
+ // type switched from credit-card to text) the IMask() reassignment
11393
+ // below is skipped, and downstream writes at line ~823 would otherwise
11394
+ // route through the destroyed instance.
11501
11395
  if (this.maskInstance) {
11502
11396
  this.maskInstance.destroy();
11397
+ this.maskInstance = null;
11503
11398
  }
11504
11399
 
11505
- // Pass new format to util
11506
11400
  this.util.updateFormat(this.format);
11507
11401
 
11508
11402
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11509
11403
 
11510
11404
  if (this.inputElement && maskOptions.mask) {
11511
-
11512
- // Stash and clear any existing value before IMask init.
11513
- // IMask's constructor processes the current input value which requires
11514
- // selection state clearing first avoids that scenario entirely.
11515
- // When the format changes (e.g. locale switch) and we have a valid ISO
11516
- // model value, compute the display string for the NEW format instead of
11517
- // re-using the old display string, which may be invalid in the new mask.
11405
+ // Capture the current display so it can be re-applied after IMask
11406
+ // attaches. The restore at the bottom goes through maskInstance.value
11407
+ // (not inputElement.value directly) so the mask's internal state and
11408
+ // the input's displayed text stay in lock-step.
11518
11409
  let existingValue = this.inputElement.value;
11410
+
11411
+ // Format-change case (e.g. locale switch): existingValue is the OLD
11412
+ // mask's display string and may not parse under the new mask. When
11413
+ // we have a valid date model, rebuild the display from valueObject
11414
+ // (the canonical source) using the new mask's format function.
11519
11415
  if (
11520
11416
  this.util.isFullDateFormat(this.type, this.format) &&
11521
11417
  this.value &&
11522
- dateFormatter.isValidDate(this.value) &&
11523
- this.valueObject instanceof Date &&
11524
- !Number.isNaN(this.valueObject.getTime()) &&
11418
+ this.valueObject &&
11525
11419
  typeof maskOptions.format === 'function'
11526
11420
  ) {
11527
11421
  existingValue = maskOptions.format(this.valueObject);
11528
11422
  }
11529
11423
 
11424
+ // Clear before IMask attaches so the constructor seeds an empty
11425
+ // internal value. Otherwise IMask reads the stale unmasked string
11426
+ // and emits a spurious 'accept' before the restore below runs.
11530
11427
  this.skipNextProgrammaticInputEvent = true;
11531
11428
  this.inputElement.value = '';
11532
11429
 
11533
11430
  this.maskInstance = IMask(this.inputElement, maskOptions);
11534
11431
 
11432
+ // Mask fires 'accept' on every value change, including the restore
11433
+ // step below. Skip events fired during configureAutoFormatting so
11434
+ // we don't overwrite a value the parent just pushed.
11535
11435
  this.maskInstance.on('accept', () => {
11536
- // Suppress propagation during configureAutoFormatting's own value-restoration
11537
- // (line below) — the mask emits 'accept' on every value-set, including ours,
11538
- // and we don't want to overwrite a value the parent just pushed.
11539
11436
  if (this._configuringMask) return;
11540
11437
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11541
11438
  if (this.type === "date") {
@@ -11543,6 +11440,8 @@ class BaseInput extends AuroElement {
11543
11440
  }
11544
11441
  });
11545
11442
 
11443
+ // Mask fires 'complete' on the restore step below for any value that
11444
+ // happens to be a complete match. Same setup-suppression as 'accept'.
11546
11445
  this.maskInstance.on('complete', () => {
11547
11446
  if (this._configuringMask) return;
11548
11447
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11551,7 +11450,9 @@ class BaseInput extends AuroElement {
11551
11450
  }
11552
11451
  });
11553
11452
 
11554
- // Restore the stashed value through IMask so it's properly masked
11453
+ // Write existingValue through the mask (not the input directly) so
11454
+ // the mask reformats it under the new rules and keeps its internal
11455
+ // _value aligned with the input's displayed text.
11555
11456
  if (existingValue) {
11556
11457
  this.maskInstance.value = existingValue;
11557
11458
  }
@@ -11631,6 +11532,38 @@ class BaseInput extends AuroElement {
11631
11532
  this.touched = true;
11632
11533
  this.validation.validate(this);
11633
11534
  }
11535
+
11536
+ // Prevents cursor jumping in Safari. Setting `this.value` triggers a Lit
11537
+ // update that can re-render the input and reset the native cursor; we
11538
+ // capture the caret position before that update commits and restore it
11539
+ // via `setSelectionRange` once the update has flushed. Gated on
11540
+ // `setSelectionInputTypes` so credit-card (and other masked types whose
11541
+ // formatter manages the cursor itself) doesn't get a competing write.
11542
+ // Capture the caret position INSIDE the gate — reading `selectionStart`
11543
+ // on input types that don't support text selection (number, email in
11544
+ // some browsers) throws InvalidStateError, which would crash all input
11545
+ // handling. Wrap the read in try/catch belt-and-suspenders even though
11546
+ // the gated types currently support it, since the list is a public
11547
+ // property a consumer could mutate.
11548
+ if (this.setSelectionInputTypes.includes(this.type)) {
11549
+ let selectionStart = null;
11550
+ try {
11551
+ ({ selectionStart } = this.inputElement);
11552
+ } catch (error) { // eslint-disable-line no-unused-vars
11553
+ return;
11554
+ }
11555
+ if (typeof selectionStart !== 'number') {
11556
+ return;
11557
+ }
11558
+ this.updateComplete.then(() => {
11559
+ try {
11560
+ this.inputElement.setSelectionRange(selectionStart, selectionStart);
11561
+ } catch (error) { // eslint-disable-line no-unused-vars
11562
+ // Some input types (number/email in certain UAs) throw on
11563
+ // setSelectionRange; swallow and let the native cursor stand.
11564
+ }
11565
+ });
11566
+ }
11634
11567
  }
11635
11568
 
11636
11569
  /**
@@ -11719,7 +11652,6 @@ class BaseInput extends AuroElement {
11719
11652
  */
11720
11653
  reset() {
11721
11654
  this.value = undefined;
11722
- this.setDateObjectProperty('valueObject', undefined);
11723
11655
  this.validation.reset(this);
11724
11656
  }
11725
11657
 
@@ -11728,7 +11660,6 @@ class BaseInput extends AuroElement {
11728
11660
  */
11729
11661
  clear() {
11730
11662
  this.value = undefined;
11731
- this.setDateObjectProperty('valueObject', undefined);
11732
11663
  }
11733
11664
 
11734
11665
  /**
@@ -11766,7 +11697,7 @@ class BaseInput extends AuroElement {
11766
11697
  */
11767
11698
  get placeholderStr() {
11768
11699
  if (!this.placeholder && this.type === 'date') {
11769
- return this.format ? this.format.toUpperCase() : 'MM/DD/YYYY';
11700
+ return this.format.toUpperCase();
11770
11701
  }
11771
11702
  return this.placeholder || "";
11772
11703
  }
@@ -12257,7 +12188,7 @@ class AuroHelpText extends i$3 {
12257
12188
  }
12258
12189
  }
12259
12190
 
12260
- var formkitVersion = '202606192121';
12191
+ var formkitVersion = '202607010100';
12261
12192
 
12262
12193
  /**
12263
12194
  * @license
@@ -12772,6 +12703,7 @@ class AuroInput extends BaseInput {
12772
12703
  <${this.buttonTag}
12773
12704
  @click="${this.handleClickShowPassword}"
12774
12705
  appearance="${this.onDark ? 'inverse' : this.appearance}"
12706
+ aria-pressed="${this.showPassword ? 'true' : 'false'}"
12775
12707
  class="notificationBtn passwordBtn"
12776
12708
  shape="circle"
12777
12709
  size="sm"
@@ -12845,25 +12777,29 @@ class AuroInput extends BaseInput {
12845
12777
  * @returns {html} - Returns HTML for the help text and error message.
12846
12778
  */
12847
12779
  renderHtmlHelpText() {
12780
+ // Single `<p>` with stable identity across validity transitions —
12781
+ // previously two distinct templates (valid vs invalid) caused Lit to
12782
+ // replace the node entirely on a flip, and VoiceOver wouldn't
12783
+ // re-announce because the live-region element it was watching had been
12784
+ // removed and a new one inserted. Keeping one node means the `role`,
12785
+ // `aria-live`, and text content all change in-place, which AT does
12786
+ // observe and announce.
12787
+ const isError = this.validity && this.validity !== 'valid';
12848
12788
  return u$4`
12849
- ${!this.validity || this.validity === undefined || this.validity === 'valid'
12850
- ? u$4`
12851
- <${this.helpTextTag}
12852
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12853
- <p id="${this.uniqueId}" part="helpText">
12854
- <slot name="helpText">${this.getHelpText()}</slot>
12855
- </p>
12856
- </${this.helpTextTag}>
12857
- `
12858
- : u$4`
12859
- <${this.helpTextTag} error
12860
- appearance="${this.onDark ? 'inverse' : this.appearance}">
12861
- <p id="${this.uniqueId}" role="alert" aria-live="assertive" part="helpText">
12862
- ${this.errorMessage}
12863
- </p>
12864
- </${this.helpTextTag}>
12865
- `
12789
+ <${this.helpTextTag}
12790
+ appearance="${this.onDark ? 'inverse' : this.appearance}"
12791
+ ?error=${isError}>
12792
+ <p
12793
+ id="${this.uniqueId}"
12794
+ part="helpText"
12795
+ role="${o$2(isError ? 'alert' : undefined)}"
12796
+ aria-live="${o$2(isError ? 'assertive' : undefined)}">
12797
+ ${isError
12798
+ ? this.errorMessage
12799
+ : u$4`<slot name="helpText">${this.getHelpText()}</slot>`
12866
12800
  }
12801
+ </p>
12802
+ </${this.helpTextTag}>
12867
12803
  `;
12868
12804
  }
12869
12805