@aurodesignsystem-dev/auro-formkit 0.0.0-pr1508.0 → 0.0.0-pr1509.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 (46) hide show
  1. package/components/checkbox/demo/customize.min.js +1 -1
  2. package/components/checkbox/demo/getting-started.min.js +1 -1
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/customize.min.js +279 -142
  7. package/components/combobox/demo/getting-started.min.js +279 -142
  8. package/components/combobox/demo/index.min.js +279 -142
  9. package/components/combobox/dist/auro-combobox.d.ts +0 -9
  10. package/components/combobox/dist/index.js +279 -142
  11. package/components/combobox/dist/registered.js +279 -142
  12. package/components/counter/demo/customize.min.js +2 -2
  13. package/components/counter/demo/index.min.js +2 -2
  14. package/components/counter/dist/index.js +2 -2
  15. package/components/counter/dist/registered.js +2 -2
  16. package/components/datepicker/demo/customize.min.js +153 -45
  17. package/components/datepicker/demo/index.min.js +153 -45
  18. package/components/datepicker/dist/index.js +153 -45
  19. package/components/datepicker/dist/registered.js +153 -45
  20. package/components/dropdown/demo/customize.min.js +1 -1
  21. package/components/dropdown/demo/getting-started.min.js +1 -1
  22. package/components/dropdown/demo/index.min.js +1 -1
  23. package/components/dropdown/dist/index.js +1 -1
  24. package/components/dropdown/dist/registered.js +1 -1
  25. package/components/form/demo/customize.min.js +589 -235
  26. package/components/form/demo/getting-started.min.js +589 -235
  27. package/components/form/demo/index.min.js +589 -235
  28. package/components/form/demo/registerDemoDeps.min.js +589 -235
  29. package/components/input/demo/customize.min.js +151 -42
  30. package/components/input/demo/getting-started.min.js +151 -42
  31. package/components/input/demo/index.min.js +151 -42
  32. package/components/input/dist/base-input.d.ts +49 -1
  33. package/components/input/dist/index.js +151 -42
  34. package/components/input/dist/registered.js +151 -42
  35. package/components/radio/demo/customize.min.js +1 -1
  36. package/components/radio/demo/getting-started.min.js +1 -1
  37. package/components/radio/demo/index.min.js +1 -1
  38. package/components/radio/dist/index.js +1 -1
  39. package/components/radio/dist/registered.js +1 -1
  40. package/components/select/demo/customize.min.js +2 -2
  41. package/components/select/demo/getting-started.min.js +2 -2
  42. package/components/select/demo/index.min.js +2 -2
  43. package/components/select/dist/index.js +2 -2
  44. package/components/select/dist/registered.js +2 -2
  45. package/custom-elements.json +264 -20
  46. package/package.json +1 -1
@@ -10389,7 +10389,6 @@ class AuroInputUtilities {
10389
10389
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10390
10390
 
10391
10391
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10392
- console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10393
10392
  return undefined;
10394
10393
  }
10395
10394
 
@@ -10541,8 +10540,10 @@ class BaseInput extends AuroElement {
10541
10540
  this.layout = 'classic';
10542
10541
  this.locale = 'en-US';
10543
10542
  this.max = undefined;
10543
+ this._maxObject = undefined;
10544
10544
  this.maxLength = undefined;
10545
10545
  this.min = undefined;
10546
+ this._minObject = undefined;
10546
10547
  this.minLength = undefined;
10547
10548
  this.required = false;
10548
10549
  this.onDark = false;
@@ -10550,6 +10551,7 @@ class BaseInput extends AuroElement {
10550
10551
  this.size = 'lg';
10551
10552
  this.shape = 'classic';
10552
10553
  this.value = undefined;
10554
+ this._valueObject = undefined;
10553
10555
 
10554
10556
  this._initializePrivateDefaults();
10555
10557
  }
@@ -11089,7 +11091,7 @@ class BaseInput extends AuroElement {
11089
11091
  * @returns {Date|undefined}
11090
11092
  */
11091
11093
  get valueObject() {
11092
- return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
11094
+ return this._valueObject || this._computeDateObjectFallback(this.value);
11093
11095
  }
11094
11096
 
11095
11097
  /**
@@ -11097,7 +11099,7 @@ class BaseInput extends AuroElement {
11097
11099
  * @returns {Date|undefined}
11098
11100
  */
11099
11101
  get minObject() {
11100
- return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
11102
+ return this._minObject || this._computeDateObjectFallback(this.min);
11101
11103
  }
11102
11104
 
11103
11105
  /**
@@ -11105,7 +11107,50 @@ class BaseInput extends AuroElement {
11105
11107
  * @returns {Date|undefined}
11106
11108
  */
11107
11109
  get maxObject() {
11108
- return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
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);
11109
11154
  }
11110
11155
 
11111
11156
  connectedCallback() {
@@ -11134,6 +11179,7 @@ class BaseInput extends AuroElement {
11134
11179
  format: this.format
11135
11180
  });
11136
11181
  this.configureDataForType();
11182
+ this.syncDateValues();
11137
11183
  }
11138
11184
 
11139
11185
  disconnectedCallback() {
@@ -11163,6 +11209,7 @@ class BaseInput extends AuroElement {
11163
11209
  this.setCustomHelpTextMessage();
11164
11210
  this.configureAutoFormatting();
11165
11211
  this.configureDataForType();
11212
+ this.syncDateValues();
11166
11213
  }
11167
11214
 
11168
11215
  /**
@@ -11238,6 +11285,13 @@ class BaseInput extends AuroElement {
11238
11285
 
11239
11286
  if (typeToI18n.includes(this.type)) {
11240
11287
  this.setCustomValidityForType = i18n(this.lang, this.type);
11288
+ // COVERAGE: this `else if` branch is unreachable in WTR. connectedCallback
11289
+ // (L682) calls configureDataForType, which at L1266-1268 assigns
11290
+ // `this.format = this.util.getDateMaskFromLocale().toLowerCase()` for any
11291
+ // type=date input whose `format` attribute is unset. That runs before
11292
+ // firstUpdated invokes setCustomHelpTextMessage, so `!this.format` is
11293
+ // always false here. Retained as a defensive fallback; the whole function
11294
+ // is @deprecated per AB#1557296 and slated for removal.
11241
11295
  } else if (!this.format && this.type === 'date') {
11242
11296
  this.setCustomValidityForType = i18n(this.lang, 'dateMMDDYYYY');
11243
11297
  } else if (this.dateFormatMap[this.format]) {
@@ -11299,6 +11353,8 @@ class BaseInput extends AuroElement {
11299
11353
  this.configureDataForType();
11300
11354
  }
11301
11355
 
11356
+ this.syncDateValues(changedProperties);
11357
+
11302
11358
  if (changedProperties.has('value')) {
11303
11359
  if (this.value && this.value.length > 0) {
11304
11360
  this.hasValue = true;
@@ -11320,14 +11376,14 @@ class BaseInput extends AuroElement {
11320
11376
 
11321
11377
  if (formattedValue !== this.inputElement.value) {
11322
11378
  this.skipNextProgrammaticInputEvent = true;
11323
- if (this.maskInstance && this.type !== 'date') {
11379
+ if (this.maskInstance && this.type === 'credit-card') {
11324
11380
  // Route through the mask so its _value and el.value stay in lock-step
11325
11381
  // (set value calls updateControl which writes el.value = displayValue).
11326
11382
  // Writing el.value directly leaves the mask thinking displayValue is
11327
- // stale; _saveSelection on the next focus/click then warns. Date is
11328
- // excluded because its formattedValue can be raw ISO when the calendar
11329
- // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11330
- // flip validity from patternMismatch to tooShort.
11383
+ // stale; _saveSelection on the next focus/click then warns. Scoped to
11384
+ // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11385
+ // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11386
+ // and flip validity from patternMismatch to tooShort.
11331
11387
  this.maskInstance.value = formattedValue || '';
11332
11388
  } else if (formattedValue) {
11333
11389
  this.inputElement.value = formattedValue;
@@ -11369,65 +11425,120 @@ class BaseInput extends AuroElement {
11369
11425
  }));
11370
11426
  }
11371
11427
 
11428
+
11429
+ /**
11430
+ * Synchronizes the ISO string values and Date object representations for date-related properties.
11431
+ * This keeps the model and display values aligned when either side changes.
11432
+ *
11433
+ * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11434
+ * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11435
+ * represents a full year/month/day date format.
11436
+ *
11437
+ * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11438
+ * @returns {void}
11439
+ * @private
11440
+ */
11441
+ syncDateValues(changedProperties = undefined) {
11442
+ if (!this.util.isFullDateFormat(this.type, this.format)) {
11443
+ return;
11444
+ }
11445
+
11446
+ this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11447
+ this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11448
+ this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11449
+ }
11450
+
11451
+ /**
11452
+ * Synchronizes one date object/string property pair.
11453
+ * @private
11454
+ * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11455
+ * @param {string} objectProperty - Date object property name.
11456
+ * @param {string} valueProperty - ISO string property name.
11457
+ * @returns {void}
11458
+ */
11459
+ syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11460
+ const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11461
+
11462
+ // objectProperty wins over valueProperty when both changed
11463
+ if (objectPropertyChanged && this[objectProperty]) {
11464
+ this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
11465
+ return;
11466
+ }
11467
+
11468
+ const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11469
+ if (!valuePropertyChanged) {
11470
+ return;
11471
+ }
11472
+
11473
+ // 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)
11474
+ if (
11475
+ changedProperties &&
11476
+ valueProperty === 'value' &&
11477
+ changedProperties.get('value') === undefined &&
11478
+ this[objectProperty] instanceof Date &&
11479
+ this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
11480
+ ) {
11481
+ return;
11482
+ }
11483
+
11484
+ if (dateFormatter.isValidDate(this[valueProperty])) {
11485
+ this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
11486
+ } else {
11487
+ this.setDateObjectProperty(objectProperty, undefined);
11488
+ }
11489
+ }
11490
+
11372
11491
  /**
11373
11492
  * Sets up IMasks and logic based on auto-formatting requirements.
11374
11493
  * @private
11375
11494
  * @returns {void}
11376
11495
  */
11377
11496
  configureAutoFormatting() {
11378
- // _configuringMask gates two things: external re-entry into this method
11379
- // while setup is mid-flight (from property changes that call back here),
11380
- // and the accept/complete listeners below both need to ignore the mask
11381
- // events fired by our own value-restore step.
11497
+ // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11498
+ // by _configuringMask above) could otherwise trigger handleInput
11499
+ // processCreditCard configureAutoFormatting before the outer call's
11500
+ // set value has finished its alignCursor pass.
11382
11501
  if (this._configuringMask) return;
11383
11502
  this._configuringMask = true;
11384
11503
  try {
11385
- // Destroy any prior mask so IMask can attach fresh under the new format.
11386
- // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11387
- // type switched from credit-card to text) the IMask() reassignment
11388
- // below is skipped, and downstream writes at line ~823 would otherwise
11389
- // route through the destroyed instance.
11390
11504
  if (this.maskInstance) {
11391
11505
  this.maskInstance.destroy();
11392
- this.maskInstance = null;
11393
11506
  }
11394
11507
 
11508
+ // Pass new format to util
11395
11509
  this.util.updateFormat(this.format);
11396
11510
 
11397
11511
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11398
11512
 
11399
11513
  if (this.inputElement && maskOptions.mask) {
11400
- // Capture the current display so it can be re-applied after IMask
11401
- // attaches. The restore at the bottom goes through maskInstance.value
11402
- // (not inputElement.value directly) so the mask's internal state and
11403
- // the input's displayed text stay in lock-step.
11404
- let existingValue = this.inputElement.value;
11405
11514
 
11406
- // Format-change case (e.g. locale switch): existingValue is the OLD
11407
- // mask's display string and may not parse under the new mask. When
11408
- // we have a valid date model, rebuild the display from valueObject
11409
- // (the canonical source) using the new mask's format function.
11515
+ // Stash and clear any existing value before IMask init.
11516
+ // IMask's constructor processes the current input value which requires
11517
+ // selection state clearing first avoids that scenario entirely.
11518
+ // When the format changes (e.g. locale switch) and we have a valid ISO
11519
+ // model value, compute the display string for the NEW format instead of
11520
+ // re-using the old display string, which may be invalid in the new mask.
11521
+ let existingValue = this.inputElement.value;
11410
11522
  if (
11411
11523
  this.util.isFullDateFormat(this.type, this.format) &&
11412
11524
  this.value &&
11413
- this.valueObject &&
11525
+ dateFormatter.isValidDate(this.value) &&
11526
+ this.valueObject instanceof Date &&
11527
+ !Number.isNaN(this.valueObject.getTime()) &&
11414
11528
  typeof maskOptions.format === 'function'
11415
11529
  ) {
11416
11530
  existingValue = maskOptions.format(this.valueObject);
11417
11531
  }
11418
11532
 
11419
- // Clear before IMask attaches so the constructor seeds an empty
11420
- // internal value. Otherwise IMask reads the stale unmasked string
11421
- // and emits a spurious 'accept' before the restore below runs.
11422
11533
  this.skipNextProgrammaticInputEvent = true;
11423
11534
  this.inputElement.value = '';
11424
11535
 
11425
11536
  this.maskInstance = IMask(this.inputElement, maskOptions);
11426
11537
 
11427
- // Mask fires 'accept' on every value change, including the restore
11428
- // step below. Skip events fired during configureAutoFormatting so
11429
- // we don't overwrite a value the parent just pushed.
11430
11538
  this.maskInstance.on('accept', () => {
11539
+ // Suppress propagation during configureAutoFormatting's own value-restoration
11540
+ // (line below) — the mask emits 'accept' on every value-set, including ours,
11541
+ // and we don't want to overwrite a value the parent just pushed.
11431
11542
  if (this._configuringMask) return;
11432
11543
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11433
11544
  if (this.type === "date") {
@@ -11435,8 +11546,6 @@ class BaseInput extends AuroElement {
11435
11546
  }
11436
11547
  });
11437
11548
 
11438
- // Mask fires 'complete' on the restore step below for any value that
11439
- // happens to be a complete match. Same setup-suppression as 'accept'.
11440
11549
  this.maskInstance.on('complete', () => {
11441
11550
  if (this._configuringMask) return;
11442
11551
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11445,9 +11554,7 @@ class BaseInput extends AuroElement {
11445
11554
  }
11446
11555
  });
11447
11556
 
11448
- // Write existingValue through the mask (not the input directly) so
11449
- // the mask reformats it under the new rules and keeps its internal
11450
- // _value aligned with the input's displayed text.
11557
+ // Restore the stashed value through IMask so it's properly masked
11451
11558
  if (existingValue) {
11452
11559
  this.maskInstance.value = existingValue;
11453
11560
  }
@@ -11615,6 +11722,7 @@ class BaseInput extends AuroElement {
11615
11722
  */
11616
11723
  reset() {
11617
11724
  this.value = undefined;
11725
+ this.setDateObjectProperty('valueObject', undefined);
11618
11726
  this.validation.reset(this);
11619
11727
  }
11620
11728
 
@@ -11623,6 +11731,7 @@ class BaseInput extends AuroElement {
11623
11731
  */
11624
11732
  clear() {
11625
11733
  this.value = undefined;
11734
+ this.setDateObjectProperty('valueObject', undefined);
11626
11735
  }
11627
11736
 
11628
11737
  /**
@@ -11660,7 +11769,7 @@ class BaseInput extends AuroElement {
11660
11769
  */
11661
11770
  get placeholderStr() {
11662
11771
  if (!this.placeholder && this.type === 'date') {
11663
- return this.format ? this.format.toUpperCase() : 'MM/DD/YYYY';
11772
+ return this.format.toUpperCase();
11664
11773
  }
11665
11774
  return this.placeholder || "";
11666
11775
  }
@@ -12151,7 +12260,7 @@ class AuroHelpText extends i$3 {
12151
12260
  }
12152
12261
  }
12153
12262
 
12154
- var formkitVersion = '202606231948';
12263
+ var formkitVersion = '202606241801';
12155
12264
 
12156
12265
  /**
12157
12266
  * @license
@@ -386,8 +386,10 @@ export default class BaseInput extends AuroElement {
386
386
  disabled: boolean;
387
387
  locale: string;
388
388
  max: any;
389
+ _maxObject: any;
389
390
  maxLength: any;
390
391
  min: any;
392
+ _minObject: any;
391
393
  minLength: any;
392
394
  required: boolean;
393
395
  onDark: boolean;
@@ -395,6 +397,7 @@ export default class BaseInput extends AuroElement {
395
397
  size: string;
396
398
  shape: string;
397
399
  value: any;
400
+ _valueObject: any;
398
401
  /**
399
402
  * Internal Defaults.
400
403
  * @private
@@ -450,6 +453,29 @@ export default class BaseInput extends AuroElement {
450
453
  * @returns {Date|undefined}
451
454
  */
452
455
  get maxObject(): Date | undefined;
456
+ /**
457
+ * Parses a date string into a Date object when the corresponding `_*Object`
458
+ * field hasn't been synced yet by `updated()`. Returns undefined when the
459
+ * input type/format isn't a full date or the string is not a valid date.
460
+ *
461
+ * Why this exists: a parent (datepicker) can call `inputN.validate()` from
462
+ * inside its own `updated()` before this input's `updated()` has run
463
+ * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
464
+ * and range checks would otherwise silently no-op (flipping the result to
465
+ * `valid` or `patternMismatch`).
466
+ * @private
467
+ * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
468
+ * @returns {Date|undefined}
469
+ */
470
+ private _computeDateObjectFallback;
471
+ /**
472
+ * Internal setter for readonly date object properties.
473
+ * @private
474
+ * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
475
+ * @param {Date|undefined} propertyValue - Value to assign.
476
+ * @returns {void}
477
+ */
478
+ private setDateObjectProperty;
453
479
  firstUpdated(): void;
454
480
  wrapperElement: Element | null | undefined;
455
481
  inputElement: HTMLInputElement | null | undefined;
@@ -484,6 +510,28 @@ export default class BaseInput extends AuroElement {
484
510
  * @returns {void} Notify validity state changed via event.
485
511
  */
486
512
  private notifyValidityChange;
513
+ /**
514
+ * Synchronizes the ISO string values and Date object representations for date-related properties.
515
+ * This keeps the model and display values aligned when either side changes.
516
+ *
517
+ * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
518
+ * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
519
+ * represents a full year/month/day date format.
520
+ *
521
+ * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
522
+ * @returns {void}
523
+ * @private
524
+ */
525
+ private syncDateValues;
526
+ /**
527
+ * Synchronizes one date object/string property pair.
528
+ * @private
529
+ * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
530
+ * @param {string} objectProperty - Date object property name.
531
+ * @param {string} valueProperty - ISO string property name.
532
+ * @returns {void}
533
+ */
534
+ private syncSingleDateValue;
487
535
  /**
488
536
  * Sets up IMasks and logic based on auto-formatting requirements.
489
537
  * @private
@@ -491,7 +539,7 @@ export default class BaseInput extends AuroElement {
491
539
  */
492
540
  private configureAutoFormatting;
493
541
  _configuringMask: boolean | undefined;
494
- maskInstance: import("imask").InputMask<any> | null | undefined;
542
+ maskInstance: import("imask").InputMask<any> | undefined;
495
543
  /**
496
544
  * Sends event notifying that the input has changed it's value.
497
545
  * @private