@aurodesignsystem-dev/auro-formkit 0.0.0-pr1516.0 → 0.0.0-pr1519.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/components/checkbox/demo/customize.min.js +18 -10
  2. package/components/checkbox/demo/getting-started.min.js +18 -10
  3. package/components/checkbox/demo/index.min.js +18 -10
  4. package/components/checkbox/dist/index.js +18 -10
  5. package/components/checkbox/dist/registered.js +18 -10
  6. package/components/combobox/README.md +1 -1
  7. package/components/combobox/demo/customize.md +2 -10
  8. package/components/combobox/demo/customize.min.js +454 -467
  9. package/components/combobox/demo/getting-started.min.js +454 -463
  10. package/components/combobox/demo/index.md +1 -1
  11. package/components/combobox/demo/index.min.js +454 -463
  12. package/components/combobox/demo/keyboard-behavior.md +2 -142
  13. package/components/combobox/demo/readme.md +1 -1
  14. package/components/combobox/demo/why-combobox.md +2 -2
  15. package/components/combobox/dist/auro-combobox.d.ts +30 -14
  16. package/components/combobox/dist/index.js +454 -463
  17. package/components/combobox/dist/registered.js +454 -463
  18. package/components/counter/demo/customize.min.js +32 -12
  19. package/components/counter/demo/index.min.js +32 -12
  20. package/components/counter/dist/index.js +32 -12
  21. package/components/counter/dist/registered.js +32 -12
  22. package/components/datepicker/demo/customize.min.js +183 -167
  23. package/components/datepicker/demo/index.min.js +183 -167
  24. package/components/datepicker/dist/index.js +183 -167
  25. package/components/datepicker/dist/registered.js +183 -167
  26. package/components/dropdown/demo/customize.min.js +14 -2
  27. package/components/dropdown/demo/getting-started.min.js +14 -2
  28. package/components/dropdown/demo/index.min.js +14 -2
  29. package/components/dropdown/dist/index.js +14 -2
  30. package/components/dropdown/dist/registered.js +14 -2
  31. package/components/form/demo/customize.min.js +851 -829
  32. package/components/form/demo/getting-started.min.js +851 -829
  33. package/components/form/demo/index.min.js +851 -829
  34. package/components/form/demo/registerDemoDeps.min.js +851 -829
  35. package/components/input/demo/api.md +58 -57
  36. package/components/input/demo/customize.min.js +114 -155
  37. package/components/input/demo/getting-started.min.js +114 -155
  38. package/components/input/demo/index.min.js +114 -155
  39. package/components/input/dist/base-input.d.ts +9 -51
  40. package/components/input/dist/index.js +114 -155
  41. package/components/input/dist/registered.js +114 -155
  42. package/components/input/dist/utilities.d.ts +9 -0
  43. package/components/radio/demo/customize.min.js +18 -10
  44. package/components/radio/demo/getting-started.min.js +18 -10
  45. package/components/radio/demo/index.min.js +18 -10
  46. package/components/radio/dist/index.js +18 -10
  47. package/components/radio/dist/registered.js +18 -10
  48. package/components/select/demo/customize.min.js +32 -12
  49. package/components/select/demo/getting-started.min.js +32 -12
  50. package/components/select/demo/index.min.js +32 -12
  51. package/components/select/dist/index.js +32 -12
  52. package/components/select/dist/registered.js +32 -12
  53. package/custom-elements.json +142 -278
  54. package/package.json +1 -1
@@ -4285,11 +4285,17 @@ class AuroFormValidation {
4285
4285
  return;
4286
4286
  }
4287
4287
 
4288
- // Validate that the date passed was the correct format and is a valid date
4288
+ // Validate that the date passed was the correct format and is a valid date.
4289
+ // For partial date formats, valueObject is never populated; validate them directly.
4289
4290
  if (elem.value && !elem.valueObject) {
4290
- elem.validity = 'patternMismatch';
4291
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
4292
- return;
4291
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
4292
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
4293
+
4294
+ if (!isValidPartial) {
4295
+ elem.validity = 'patternMismatch';
4296
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
4297
+ return;
4298
+ }
4293
4299
  }
4294
4300
 
4295
4301
  // Perform the rest of the validation
@@ -4383,15 +4389,17 @@ class AuroFormValidation {
4383
4389
  );
4384
4390
  }
4385
4391
 
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) {
4392
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4393
+
4394
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
4395
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
4396
+ // field (datepicker is the intended consumer — start/end are independently required).
4397
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
4398
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
4389
4399
  hasValue = false;
4390
4400
  }
4391
4401
  }
4392
4402
 
4393
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4394
-
4395
4403
  if (isCombobox) {
4396
4404
 
4397
4405
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -10291,6 +10299,42 @@ class AuroInputUtilities {
10291
10299
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
10292
10300
  }
10293
10301
 
10302
+ /**
10303
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
10304
+ * Single-component formats are checked as integer ranges; multi-component formats use
10305
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
10306
+ * @param {string} value - The user-facing display value.
10307
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
10308
+ * @returns {boolean}
10309
+ */
10310
+ isValidPartialDate(value, format$1) {
10311
+ if (!value || !format$1) {
10312
+ return false;
10313
+ }
10314
+ const normalizedFormat = format$1.toLowerCase();
10315
+
10316
+ if (normalizedFormat === 'dd') {
10317
+ const num = Number(value);
10318
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
10319
+ }
10320
+ if (normalizedFormat === 'yy') {
10321
+ const num = Number(value);
10322
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
10323
+ }
10324
+ if (normalizedFormat === 'yyyy') {
10325
+ const num = Number(value);
10326
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
10327
+ }
10328
+
10329
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
10330
+ // Use the 1st of the current month as the reference so that formats
10331
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
10332
+ const referenceDate = new Date();
10333
+ referenceDate.setDate(1);
10334
+ const parsed = parse(value, dateFnsMask, referenceDate);
10335
+ return isValid(parsed) && format(parsed, dateFnsMask) === value;
10336
+ }
10337
+
10294
10338
  /**
10295
10339
  * Converts a display string to its model value.
10296
10340
  * For full date formats, converts the display string to an ISO date string.
@@ -10338,6 +10382,7 @@ class AuroInputUtilities {
10338
10382
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10339
10383
 
10340
10384
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10385
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10341
10386
  return undefined;
10342
10387
  }
10343
10388
 
@@ -10495,6 +10540,7 @@ class BaseInput extends AuroElement {
10495
10540
  // so a parent (datepicker/combobox) calling `validate()` synchronously
10496
10541
  // during its own update cycle sees a populated util instance.
10497
10542
  this.activeLabel = false;
10543
+
10498
10544
  /** @private */
10499
10545
  this.allowedInputTypes = [
10500
10546
  "text",
@@ -10505,6 +10551,7 @@ class BaseInput extends AuroElement {
10505
10551
  "tel"
10506
10552
  ];
10507
10553
  this.appearance = "default";
10554
+
10508
10555
  /** @private */
10509
10556
  this.dateFormatMap = {
10510
10557
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -10523,23 +10570,24 @@ class BaseInput extends AuroElement {
10523
10570
  'mm/dd': 'dateMMDD'
10524
10571
  };
10525
10572
  this.disabled = false;
10573
+
10526
10574
  /** @private */
10527
10575
  this.domHandler = new DomHandler();
10528
10576
  this.dvInputOnly = false;
10529
10577
  this.hasValue = false;
10530
10578
  this.hideLabelVisually = false;
10531
10579
  this.icon = false;
10580
+
10532
10581
  /** @private */
10533
10582
  this.inputIconName = undefined;
10583
+
10534
10584
  /** @private */
10535
10585
  this.label = 'Input label is undefined';
10536
10586
  this.layout = 'classic';
10537
10587
  this.locale = 'en-US';
10538
10588
  this.max = undefined;
10539
- this._maxObject = undefined;
10540
10589
  this.maxLength = undefined;
10541
10590
  this.min = undefined;
10542
- this._minObject = undefined;
10543
10591
  this.minLength = undefined;
10544
10592
  this.noValidate = false;
10545
10593
  this.onDark = false;
@@ -10556,23 +10604,27 @@ class BaseInput extends AuroElement {
10556
10604
  "email"
10557
10605
  ];
10558
10606
  this.shape = 'classic';
10607
+
10559
10608
  /** @private */
10560
10609
  this.showPassword = false;
10561
10610
  this.size = 'lg';
10562
10611
  this.touched = false;
10612
+
10563
10613
  /** @private */
10564
10614
  this.uniqueId = new UniqueId().create();
10615
+
10565
10616
  /** @private */
10566
10617
  this.util = new AuroInputUtilities({
10567
10618
  locale: this.locale,
10568
10619
  format: this.format
10569
10620
  });
10621
+
10570
10622
  /** @private */
10571
10623
  this.validation = new AuroFormValidation();
10624
+
10572
10625
  /** @private */
10573
10626
  this.validationCCLength = undefined;
10574
10627
  this.value = undefined;
10575
- this._valueObject = undefined;
10576
10628
  }
10577
10629
 
10578
10630
  // function to define props used within the scope of this component
@@ -10902,6 +10954,13 @@ class BaseInput extends AuroElement {
10902
10954
  type: String
10903
10955
  },
10904
10956
 
10957
+ /**
10958
+ * Custom help text message to display when validity = `patternMismatch`.
10959
+ */
10960
+ setCustomValidityPatternMismatch: {
10961
+ type: String
10962
+ },
10963
+
10905
10964
  /**
10906
10965
  * Custom help text message to display when validity = `rangeOverflow`.
10907
10966
  */
@@ -10972,7 +11031,7 @@ class BaseInput extends AuroElement {
10972
11031
 
10973
11032
  /**
10974
11033
  * Populates the `type` attribute on the input.
10975
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
11034
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
10976
11035
  * @default 'text'
10977
11036
  */
10978
11037
  type: {
@@ -11010,7 +11069,7 @@ class BaseInput extends AuroElement {
11010
11069
  * @returns {Date|undefined}
11011
11070
  */
11012
11071
  get valueObject() {
11013
- return this._valueObject || this._computeDateObjectFallback(this.value);
11072
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
11014
11073
  }
11015
11074
 
11016
11075
  /**
@@ -11018,7 +11077,7 @@ class BaseInput extends AuroElement {
11018
11077
  * @returns {Date|undefined}
11019
11078
  */
11020
11079
  get minObject() {
11021
- return this._minObject || this._computeDateObjectFallback(this.min);
11080
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
11022
11081
  }
11023
11082
 
11024
11083
  /**
@@ -11026,50 +11085,7 @@ class BaseInput extends AuroElement {
11026
11085
  * @returns {Date|undefined}
11027
11086
  */
11028
11087
  get maxObject() {
11029
- return this._maxObject || this._computeDateObjectFallback(this.max);
11030
- }
11031
-
11032
- /**
11033
- * Parses a date string into a Date object when the corresponding `_*Object`
11034
- * field hasn't been synced yet by `updated()`. Returns undefined when the
11035
- * input type/format isn't a full date or the string is not a valid date.
11036
- *
11037
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
11038
- * inside its own `updated()` before this input's `updated()` has run
11039
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
11040
- * and range checks would otherwise silently no-op (flipping the result to
11041
- * `valid` or `patternMismatch`).
11042
- * @private
11043
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
11044
- * @returns {Date|undefined}
11045
- */
11046
- _computeDateObjectFallback(dateStr) {
11047
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
11048
- return undefined;
11049
- }
11050
- if (!dateFormatter.isValidDate(dateStr)) {
11051
- return undefined;
11052
- }
11053
- return dateFormatter.stringToDateInstance(dateStr);
11054
- }
11055
-
11056
- /**
11057
- * Internal setter for readonly date object properties.
11058
- * @private
11059
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
11060
- * @param {Date|undefined} propertyValue - Value to assign.
11061
- * @returns {void}
11062
- */
11063
- setDateObjectProperty(propertyName, propertyValue) {
11064
- const internalPropertyName = `_${propertyName}`;
11065
- const previousValue = this[internalPropertyName];
11066
-
11067
- if (previousValue === propertyValue) {
11068
- return;
11069
- }
11070
-
11071
- this[internalPropertyName] = propertyValue;
11072
- this.requestUpdate(propertyName, previousValue);
11088
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
11073
11089
  }
11074
11090
 
11075
11091
  connectedCallback() {
@@ -11098,7 +11114,6 @@ class BaseInput extends AuroElement {
11098
11114
  format: this.format
11099
11115
  });
11100
11116
  this.configureDataForType();
11101
- this.syncDateValues();
11102
11117
  }
11103
11118
 
11104
11119
  disconnectedCallback() {
@@ -11137,7 +11152,6 @@ class BaseInput extends AuroElement {
11137
11152
  this.setCustomHelpTextMessage();
11138
11153
  this.configureAutoFormatting();
11139
11154
  this.configureDataForType();
11140
- this.syncDateValues();
11141
11155
  }
11142
11156
 
11143
11157
  /**
@@ -11281,8 +11295,6 @@ class BaseInput extends AuroElement {
11281
11295
  this.configureDataForType();
11282
11296
  }
11283
11297
 
11284
- this.syncDateValues(changedProperties);
11285
-
11286
11298
  if (changedProperties.has('value')) {
11287
11299
  if (this.value && this.value.length > 0) {
11288
11300
  this.hasValue = true;
@@ -11304,14 +11316,14 @@ class BaseInput extends AuroElement {
11304
11316
 
11305
11317
  if (formattedValue !== this.inputElement.value) {
11306
11318
  this.skipNextProgrammaticInputEvent = true;
11307
- if (this.maskInstance && this.type === 'credit-card') {
11319
+ if (this.maskInstance && this.type !== 'date') {
11308
11320
  // Route through the mask so its _value and el.value stay in lock-step
11309
11321
  // (set value calls updateControl which writes el.value = displayValue).
11310
11322
  // Writing el.value directly leaves the mask thinking displayValue is
11311
- // stale; _saveSelection on the next focus/click then warns. Scoped to
11312
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11313
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11314
- // and flip validity from patternMismatch to tooShort.
11323
+ // stale; _saveSelection on the next focus/click then warns. Date is
11324
+ // excluded because its formattedValue can be raw ISO when the calendar
11325
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11326
+ // flip validity from patternMismatch to tooShort.
11315
11327
  this.maskInstance.value = formattedValue || '';
11316
11328
  } else if (formattedValue) {
11317
11329
  this.inputElement.value = formattedValue;
@@ -11353,120 +11365,65 @@ class BaseInput extends AuroElement {
11353
11365
  }));
11354
11366
  }
11355
11367
 
11356
-
11357
- /**
11358
- * Synchronizes the ISO string values and Date object representations for date-related properties.
11359
- * This keeps the model and display values aligned when either side changes.
11360
- *
11361
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11362
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11363
- * represents a full year/month/day date format.
11364
- *
11365
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11366
- * @returns {void}
11367
- * @private
11368
- */
11369
- syncDateValues(changedProperties = undefined) {
11370
- if (!this.util.isFullDateFormat(this.type, this.format)) {
11371
- return;
11372
- }
11373
-
11374
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11375
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11376
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11377
- }
11378
-
11379
- /**
11380
- * Synchronizes one date object/string property pair.
11381
- * @private
11382
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11383
- * @param {string} objectProperty - Date object property name.
11384
- * @param {string} valueProperty - ISO string property name.
11385
- * @returns {void}
11386
- */
11387
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11388
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11389
-
11390
- // objectProperty wins over valueProperty when both changed
11391
- if (objectPropertyChanged && this[objectProperty]) {
11392
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
11393
- return;
11394
- }
11395
-
11396
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11397
- if (!valuePropertyChanged) {
11398
- return;
11399
- }
11400
-
11401
- // 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)
11402
- if (
11403
- changedProperties &&
11404
- valueProperty === 'value' &&
11405
- changedProperties.get('value') === undefined &&
11406
- this[objectProperty] instanceof Date &&
11407
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
11408
- ) {
11409
- return;
11410
- }
11411
-
11412
- if (dateFormatter.isValidDate(this[valueProperty])) {
11413
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
11414
- } else {
11415
- this.setDateObjectProperty(objectProperty, undefined);
11416
- }
11417
- }
11418
-
11419
11368
  /**
11420
11369
  * Sets up IMasks and logic based on auto-formatting requirements.
11421
11370
  * @private
11422
11371
  * @returns {void}
11423
11372
  */
11424
11373
  configureAutoFormatting() {
11425
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11426
- // by _configuringMask above) could otherwise trigger handleInput
11427
- // processCreditCard configureAutoFormatting before the outer call's
11428
- // set value has finished its alignCursor pass.
11374
+ // _configuringMask gates two things: external re-entry into this method
11375
+ // while setup is mid-flight (from property changes that call back here),
11376
+ // and the accept/complete listeners below — both need to ignore the mask
11377
+ // events fired by our own value-restore step.
11429
11378
  if (this._configuringMask) return;
11430
11379
  this._configuringMask = true;
11431
11380
  try {
11381
+ // Destroy any prior mask so IMask can attach fresh under the new format.
11382
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11383
+ // type switched from credit-card to text) the IMask() reassignment
11384
+ // below is skipped, and downstream writes at line ~823 would otherwise
11385
+ // route through the destroyed instance.
11432
11386
  if (this.maskInstance) {
11433
11387
  this.maskInstance.destroy();
11388
+ this.maskInstance = null;
11434
11389
  }
11435
11390
 
11436
- // Pass new format to util
11437
11391
  this.util.updateFormat(this.format);
11438
11392
 
11439
11393
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11440
11394
 
11441
11395
  if (this.inputElement && maskOptions.mask) {
11442
-
11443
- // Stash and clear any existing value before IMask init.
11444
- // IMask's constructor processes the current input value which requires
11445
- // selection state clearing first avoids that scenario entirely.
11446
- // When the format changes (e.g. locale switch) and we have a valid ISO
11447
- // model value, compute the display string for the NEW format instead of
11448
- // re-using the old display string, which may be invalid in the new mask.
11396
+ // Capture the current display so it can be re-applied after IMask
11397
+ // attaches. The restore at the bottom goes through maskInstance.value
11398
+ // (not inputElement.value directly) so the mask's internal state and
11399
+ // the input's displayed text stay in lock-step.
11449
11400
  let existingValue = this.inputElement.value;
11401
+
11402
+ // Format-change case (e.g. locale switch): existingValue is the OLD
11403
+ // mask's display string and may not parse under the new mask. When
11404
+ // we have a valid date model, rebuild the display from valueObject
11405
+ // (the canonical source) using the new mask's format function.
11450
11406
  if (
11451
11407
  this.util.isFullDateFormat(this.type, this.format) &&
11452
11408
  this.value &&
11453
- dateFormatter.isValidDate(this.value) &&
11454
- this.valueObject instanceof Date &&
11455
- !Number.isNaN(this.valueObject.getTime()) &&
11409
+ this.valueObject &&
11456
11410
  typeof maskOptions.format === 'function'
11457
11411
  ) {
11458
11412
  existingValue = maskOptions.format(this.valueObject);
11459
11413
  }
11460
11414
 
11415
+ // Clear before IMask attaches so the constructor seeds an empty
11416
+ // internal value. Otherwise IMask reads the stale unmasked string
11417
+ // and emits a spurious 'accept' before the restore below runs.
11461
11418
  this.skipNextProgrammaticInputEvent = true;
11462
11419
  this.inputElement.value = '';
11463
11420
 
11464
11421
  this.maskInstance = IMask(this.inputElement, maskOptions);
11465
11422
 
11423
+ // Mask fires 'accept' on every value change, including the restore
11424
+ // step below. Skip events fired during configureAutoFormatting so
11425
+ // we don't overwrite a value the parent just pushed.
11466
11426
  this.maskInstance.on('accept', () => {
11467
- // Suppress propagation during configureAutoFormatting's own value-restoration
11468
- // (line below) — the mask emits 'accept' on every value-set, including ours,
11469
- // and we don't want to overwrite a value the parent just pushed.
11470
11427
  if (this._configuringMask) return;
11471
11428
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11472
11429
  if (this.type === "date") {
@@ -11474,6 +11431,8 @@ class BaseInput extends AuroElement {
11474
11431
  }
11475
11432
  });
11476
11433
 
11434
+ // Mask fires 'complete' on the restore step below for any value that
11435
+ // happens to be a complete match. Same setup-suppression as 'accept'.
11477
11436
  this.maskInstance.on('complete', () => {
11478
11437
  if (this._configuringMask) return;
11479
11438
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11482,7 +11441,9 @@ class BaseInput extends AuroElement {
11482
11441
  }
11483
11442
  });
11484
11443
 
11485
- // Restore the stashed value through IMask so it's properly masked
11444
+ // Write existingValue through the mask (not the input directly) so
11445
+ // the mask reformats it under the new rules and keeps its internal
11446
+ // _value aligned with the input's displayed text.
11486
11447
  if (existingValue) {
11487
11448
  this.maskInstance.value = existingValue;
11488
11449
  }
@@ -11576,9 +11537,9 @@ class BaseInput extends AuroElement {
11576
11537
  // the gated types currently support it, since the list is a public
11577
11538
  // property a consumer could mutate.
11578
11539
  if (this.setSelectionInputTypes.includes(this.type)) {
11579
- let selectionStart;
11540
+ let selectionStart = null;
11580
11541
  try {
11581
- selectionStart = this.inputElement.selectionStart;
11542
+ ({ selectionStart } = this.inputElement);
11582
11543
  } catch (error) { // eslint-disable-line no-unused-vars
11583
11544
  return;
11584
11545
  }
@@ -11682,7 +11643,6 @@ class BaseInput extends AuroElement {
11682
11643
  */
11683
11644
  reset() {
11684
11645
  this.value = undefined;
11685
- this.setDateObjectProperty('valueObject', undefined);
11686
11646
  this.validation.reset(this);
11687
11647
  }
11688
11648
 
@@ -11691,7 +11651,6 @@ class BaseInput extends AuroElement {
11691
11651
  */
11692
11652
  clear() {
11693
11653
  this.value = undefined;
11694
- this.setDateObjectProperty('valueObject', undefined);
11695
11654
  }
11696
11655
 
11697
11656
  /**
@@ -12220,7 +12179,7 @@ class AuroHelpText extends LitElement {
12220
12179
  }
12221
12180
  }
12222
12181
 
12223
- var formkitVersion = '202606292156';
12182
+ var formkitVersion = '202607011722';
12224
12183
 
12225
12184
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12226
12185
  // See LICENSE in the project root for license information.
@@ -62,6 +62,15 @@ export class AuroInputUtilities {
62
62
  * @returns {boolean}
63
63
  */
64
64
  private isFullDateFormat;
65
+ /**
66
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
67
+ * Single-component formats are checked as integer ranges; multi-component formats use
68
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
69
+ * @param {string} value - The user-facing display value.
70
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
71
+ * @returns {boolean}
72
+ */
73
+ isValidPartialDate(value: string, format: string): boolean;
65
74
  /**
66
75
  * Converts a display string to its model value.
67
76
  * For full date formats, converts the display string to an ISO date string.
@@ -715,11 +715,17 @@ class AuroFormValidation {
715
715
  return;
716
716
  }
717
717
 
718
- // Validate that the date passed was the correct format and is a valid date
718
+ // Validate that the date passed was the correct format and is a valid date.
719
+ // For partial date formats, valueObject is never populated; validate them directly.
719
720
  if (elem.value && !elem.valueObject) {
720
- elem.validity = 'patternMismatch';
721
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
722
- return;
721
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
722
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
723
+
724
+ if (!isValidPartial) {
725
+ elem.validity = 'patternMismatch';
726
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
727
+ return;
728
+ }
723
729
  }
724
730
 
725
731
  // Perform the rest of the validation
@@ -813,15 +819,17 @@ class AuroFormValidation {
813
819
  );
814
820
  }
815
821
 
816
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
817
- if (this.auroInputElements?.length === 2) {
818
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
822
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
823
+
824
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
825
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
826
+ // field (datepicker is the intended consumer — start/end are independently required).
827
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
828
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
819
829
  hasValue = false;
820
830
  }
821
831
  }
822
832
 
823
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
824
-
825
833
  if (isCombobox) {
826
834
 
827
835
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -1212,7 +1220,7 @@ class AuroHelpText extends i$2 {
1212
1220
  }
1213
1221
  }
1214
1222
 
1215
- var formkitVersion = '202606292156';
1223
+ var formkitVersion = '202607011722';
1216
1224
 
1217
1225
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
1218
1226
  // See LICENSE in the project root for license information.
@@ -715,11 +715,17 @@ class AuroFormValidation {
715
715
  return;
716
716
  }
717
717
 
718
- // Validate that the date passed was the correct format and is a valid date
718
+ // Validate that the date passed was the correct format and is a valid date.
719
+ // For partial date formats, valueObject is never populated; validate them directly.
719
720
  if (elem.value && !elem.valueObject) {
720
- elem.validity = 'patternMismatch';
721
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
722
- return;
721
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
722
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
723
+
724
+ if (!isValidPartial) {
725
+ elem.validity = 'patternMismatch';
726
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
727
+ return;
728
+ }
723
729
  }
724
730
 
725
731
  // Perform the rest of the validation
@@ -813,15 +819,17 @@ class AuroFormValidation {
813
819
  );
814
820
  }
815
821
 
816
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
817
- if (this.auroInputElements?.length === 2) {
818
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
822
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
823
+
824
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
825
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
826
+ // field (datepicker is the intended consumer — start/end are independently required).
827
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
828
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
819
829
  hasValue = false;
820
830
  }
821
831
  }
822
832
 
823
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
824
-
825
833
  if (isCombobox) {
826
834
 
827
835
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -1212,7 +1220,7 @@ class AuroHelpText extends i$2 {
1212
1220
  }
1213
1221
  }
1214
1222
 
1215
- var formkitVersion = '202606292156';
1223
+ var formkitVersion = '202607011722';
1216
1224
 
1217
1225
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
1218
1226
  // See LICENSE in the project root for license information.