@aurodesignsystem-dev/auro-formkit 0.0.0-pr1506.1 → 0.0.0-pr1507.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.
- package/components/checkbox/demo/customize.min.js +1 -1
- package/components/checkbox/demo/getting-started.min.js +1 -1
- package/components/checkbox/demo/index.min.js +1 -1
- package/components/checkbox/dist/index.js +1 -1
- package/components/checkbox/dist/registered.js +1 -1
- package/components/combobox/demo/customize.min.js +268 -140
- package/components/combobox/demo/getting-started.min.js +268 -140
- package/components/combobox/demo/index.min.js +268 -140
- package/components/combobox/dist/auro-combobox.d.ts +0 -9
- package/components/combobox/dist/index.js +266 -138
- package/components/combobox/dist/registered.js +266 -138
- package/components/counter/demo/customize.min.js +2 -2
- package/components/counter/demo/index.min.js +2 -2
- package/components/counter/dist/index.js +2 -2
- package/components/counter/dist/registered.js +2 -2
- package/components/datepicker/demo/customize.min.js +149 -39
- package/components/datepicker/demo/index.min.js +149 -39
- package/components/datepicker/dist/index.js +149 -39
- package/components/datepicker/dist/registered.js +149 -39
- package/components/dropdown/demo/customize.min.js +1 -1
- package/components/dropdown/demo/getting-started.min.js +1 -1
- package/components/dropdown/demo/index.min.js +1 -1
- package/components/dropdown/dist/index.js +1 -1
- package/components/dropdown/dist/registered.js +1 -1
- package/components/form/demo/customize.min.js +570 -221
- package/components/form/demo/getting-started.min.js +570 -221
- package/components/form/demo/index.min.js +570 -221
- package/components/form/demo/registerDemoDeps.min.js +570 -221
- package/components/input/demo/customize.min.js +147 -36
- package/components/input/demo/getting-started.min.js +147 -36
- package/components/input/demo/index.min.js +147 -36
- package/components/input/dist/base-input.d.ts +48 -0
- package/components/input/dist/index.js +147 -36
- package/components/input/dist/registered.js +147 -36
- package/components/menu/demo/index.min.js +2 -2
- package/components/menu/dist/index.js +2 -2
- package/components/menu/dist/registered.js +2 -2
- package/components/radio/demo/customize.min.js +1 -1
- package/components/radio/demo/getting-started.min.js +1 -1
- package/components/radio/demo/index.min.js +1 -1
- package/components/radio/dist/index.js +1 -1
- package/components/radio/dist/registered.js +1 -1
- package/components/select/demo/customize.min.js +4 -4
- package/components/select/demo/getting-started.min.js +4 -4
- package/components/select/demo/index.min.js +4 -4
- package/components/select/dist/index.js +2 -2
- package/components/select/dist/registered.js +2 -2
- package/custom-elements.json +264 -20
- package/package.json +1 -1
|
@@ -10331,7 +10331,6 @@ class AuroInputUtilities {
|
|
|
10331
10331
|
const maskOptions = this.getMaskOptions('date', normalizedFormat);
|
|
10332
10332
|
|
|
10333
10333
|
if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
|
|
10334
|
-
console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
|
|
10335
10334
|
return undefined;
|
|
10336
10335
|
}
|
|
10337
10336
|
|
|
@@ -10483,8 +10482,10 @@ class BaseInput extends AuroElement {
|
|
|
10483
10482
|
this.layout = 'classic';
|
|
10484
10483
|
this.locale = 'en-US';
|
|
10485
10484
|
this.max = undefined;
|
|
10485
|
+
this._maxObject = undefined;
|
|
10486
10486
|
this.maxLength = undefined;
|
|
10487
10487
|
this.min = undefined;
|
|
10488
|
+
this._minObject = undefined;
|
|
10488
10489
|
this.minLength = undefined;
|
|
10489
10490
|
this.required = false;
|
|
10490
10491
|
this.onDark = false;
|
|
@@ -10492,6 +10493,7 @@ class BaseInput extends AuroElement {
|
|
|
10492
10493
|
this.size = 'lg';
|
|
10493
10494
|
this.shape = 'classic';
|
|
10494
10495
|
this.value = undefined;
|
|
10496
|
+
this._valueObject = undefined;
|
|
10495
10497
|
|
|
10496
10498
|
this._initializePrivateDefaults();
|
|
10497
10499
|
}
|
|
@@ -11031,7 +11033,7 @@ class BaseInput extends AuroElement {
|
|
|
11031
11033
|
* @returns {Date|undefined}
|
|
11032
11034
|
*/
|
|
11033
11035
|
get valueObject() {
|
|
11034
|
-
return this.
|
|
11036
|
+
return this._valueObject || this._computeDateObjectFallback(this.value);
|
|
11035
11037
|
}
|
|
11036
11038
|
|
|
11037
11039
|
/**
|
|
@@ -11039,7 +11041,7 @@ class BaseInput extends AuroElement {
|
|
|
11039
11041
|
* @returns {Date|undefined}
|
|
11040
11042
|
*/
|
|
11041
11043
|
get minObject() {
|
|
11042
|
-
return this.
|
|
11044
|
+
return this._minObject || this._computeDateObjectFallback(this.min);
|
|
11043
11045
|
}
|
|
11044
11046
|
|
|
11045
11047
|
/**
|
|
@@ -11047,7 +11049,50 @@ class BaseInput extends AuroElement {
|
|
|
11047
11049
|
* @returns {Date|undefined}
|
|
11048
11050
|
*/
|
|
11049
11051
|
get maxObject() {
|
|
11050
|
-
return this.
|
|
11052
|
+
return this._maxObject || this._computeDateObjectFallback(this.max);
|
|
11053
|
+
}
|
|
11054
|
+
|
|
11055
|
+
/**
|
|
11056
|
+
* Parses a date string into a Date object when the corresponding `_*Object`
|
|
11057
|
+
* field hasn't been synced yet by `updated()`. Returns undefined when the
|
|
11058
|
+
* input type/format isn't a full date or the string is not a valid date.
|
|
11059
|
+
*
|
|
11060
|
+
* Why this exists: a parent (datepicker) can call `inputN.validate()` from
|
|
11061
|
+
* inside its own `updated()` before this input's `updated()` has run
|
|
11062
|
+
* `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
|
|
11063
|
+
* and range checks would otherwise silently no-op (flipping the result to
|
|
11064
|
+
* `valid` or `patternMismatch`).
|
|
11065
|
+
* @private
|
|
11066
|
+
* @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
|
|
11067
|
+
* @returns {Date|undefined}
|
|
11068
|
+
*/
|
|
11069
|
+
_computeDateObjectFallback(dateStr) {
|
|
11070
|
+
if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
|
|
11071
|
+
return undefined;
|
|
11072
|
+
}
|
|
11073
|
+
if (!dateFormatter.isValidDate(dateStr)) {
|
|
11074
|
+
return undefined;
|
|
11075
|
+
}
|
|
11076
|
+
return dateFormatter.stringToDateInstance(dateStr);
|
|
11077
|
+
}
|
|
11078
|
+
|
|
11079
|
+
/**
|
|
11080
|
+
* Internal setter for readonly date object properties.
|
|
11081
|
+
* @private
|
|
11082
|
+
* @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
|
|
11083
|
+
* @param {Date|undefined} propertyValue - Value to assign.
|
|
11084
|
+
* @returns {void}
|
|
11085
|
+
*/
|
|
11086
|
+
setDateObjectProperty(propertyName, propertyValue) {
|
|
11087
|
+
const internalPropertyName = `_${propertyName}`;
|
|
11088
|
+
const previousValue = this[internalPropertyName];
|
|
11089
|
+
|
|
11090
|
+
if (previousValue === propertyValue) {
|
|
11091
|
+
return;
|
|
11092
|
+
}
|
|
11093
|
+
|
|
11094
|
+
this[internalPropertyName] = propertyValue;
|
|
11095
|
+
this.requestUpdate(propertyName, previousValue);
|
|
11051
11096
|
}
|
|
11052
11097
|
|
|
11053
11098
|
connectedCallback() {
|
|
@@ -11076,6 +11121,7 @@ class BaseInput extends AuroElement {
|
|
|
11076
11121
|
format: this.format
|
|
11077
11122
|
});
|
|
11078
11123
|
this.configureDataForType();
|
|
11124
|
+
this.syncDateValues();
|
|
11079
11125
|
}
|
|
11080
11126
|
|
|
11081
11127
|
disconnectedCallback() {
|
|
@@ -11095,6 +11141,10 @@ class BaseInput extends AuroElement {
|
|
|
11095
11141
|
this.wrapperElement.addEventListener('click', this.handleClick);
|
|
11096
11142
|
}
|
|
11097
11143
|
|
|
11144
|
+
// add attribute for query selectors when auro-input is registered under a custom name
|
|
11145
|
+
if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
|
|
11146
|
+
this.setAttribute('auro-input', '');
|
|
11147
|
+
}
|
|
11098
11148
|
this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
|
|
11099
11149
|
|
|
11100
11150
|
// use validity message override if declared when initializing the component
|
|
@@ -11105,6 +11155,7 @@ class BaseInput extends AuroElement {
|
|
|
11105
11155
|
this.setCustomHelpTextMessage();
|
|
11106
11156
|
this.configureAutoFormatting();
|
|
11107
11157
|
this.configureDataForType();
|
|
11158
|
+
this.syncDateValues();
|
|
11108
11159
|
}
|
|
11109
11160
|
|
|
11110
11161
|
/**
|
|
@@ -11241,6 +11292,8 @@ class BaseInput extends AuroElement {
|
|
|
11241
11292
|
this.configureDataForType();
|
|
11242
11293
|
}
|
|
11243
11294
|
|
|
11295
|
+
this.syncDateValues(changedProperties);
|
|
11296
|
+
|
|
11244
11297
|
if (changedProperties.has('value')) {
|
|
11245
11298
|
if (this.value && this.value.length > 0) {
|
|
11246
11299
|
this.hasValue = true;
|
|
@@ -11262,14 +11315,14 @@ class BaseInput extends AuroElement {
|
|
|
11262
11315
|
|
|
11263
11316
|
if (formattedValue !== this.inputElement.value) {
|
|
11264
11317
|
this.skipNextProgrammaticInputEvent = true;
|
|
11265
|
-
if (this.maskInstance && this.type
|
|
11318
|
+
if (this.maskInstance && this.type === 'credit-card') {
|
|
11266
11319
|
// Route through the mask so its _value and el.value stay in lock-step
|
|
11267
11320
|
// (set value calls updateControl which writes el.value = displayValue).
|
|
11268
11321
|
// Writing el.value directly leaves the mask thinking displayValue is
|
|
11269
|
-
// stale; _saveSelection on the next focus/click then warns.
|
|
11270
|
-
//
|
|
11271
|
-
//
|
|
11272
|
-
// flip validity from patternMismatch to tooShort.
|
|
11322
|
+
// stale; _saveSelection on the next focus/click then warns. Scoped to
|
|
11323
|
+
// credit-card so date's own formattedValue (raw ISO when calendar-invalid)
|
|
11324
|
+
// isn't re-masked through the mm/dd/yyyy mask, which would truncate it
|
|
11325
|
+
// and flip validity from patternMismatch to tooShort.
|
|
11273
11326
|
this.maskInstance.value = formattedValue || '';
|
|
11274
11327
|
} else if (formattedValue) {
|
|
11275
11328
|
this.inputElement.value = formattedValue;
|
|
@@ -11311,60 +11364,120 @@ class BaseInput extends AuroElement {
|
|
|
11311
11364
|
}));
|
|
11312
11365
|
}
|
|
11313
11366
|
|
|
11367
|
+
|
|
11368
|
+
/**
|
|
11369
|
+
* Synchronizes the ISO string values and Date object representations for date-related properties.
|
|
11370
|
+
* This keeps the model and display values aligned when either side changes.
|
|
11371
|
+
*
|
|
11372
|
+
* When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
|
|
11373
|
+
* Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
|
|
11374
|
+
* represents a full year/month/day date format.
|
|
11375
|
+
*
|
|
11376
|
+
* @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
|
|
11377
|
+
* @returns {void}
|
|
11378
|
+
* @private
|
|
11379
|
+
*/
|
|
11380
|
+
syncDateValues(changedProperties = undefined) {
|
|
11381
|
+
if (!this.util.isFullDateFormat(this.type, this.format)) {
|
|
11382
|
+
return;
|
|
11383
|
+
}
|
|
11384
|
+
|
|
11385
|
+
this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
|
|
11386
|
+
this.syncSingleDateValue(changedProperties, 'minObject', 'min');
|
|
11387
|
+
this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
|
|
11388
|
+
}
|
|
11389
|
+
|
|
11390
|
+
/**
|
|
11391
|
+
* Synchronizes one date object/string property pair.
|
|
11392
|
+
* @private
|
|
11393
|
+
* @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
|
|
11394
|
+
* @param {string} objectProperty - Date object property name.
|
|
11395
|
+
* @param {string} valueProperty - ISO string property name.
|
|
11396
|
+
* @returns {void}
|
|
11397
|
+
*/
|
|
11398
|
+
syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
|
|
11399
|
+
const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
|
|
11400
|
+
|
|
11401
|
+
// objectProperty wins over valueProperty when both changed
|
|
11402
|
+
if (objectPropertyChanged && this[objectProperty]) {
|
|
11403
|
+
this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
|
|
11404
|
+
return;
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11407
|
+
const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
|
|
11408
|
+
if (!valuePropertyChanged) {
|
|
11409
|
+
return;
|
|
11410
|
+
}
|
|
11411
|
+
|
|
11412
|
+
// when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
|
|
11413
|
+
if (
|
|
11414
|
+
changedProperties &&
|
|
11415
|
+
valueProperty === 'value' &&
|
|
11416
|
+
changedProperties.get('value') === undefined &&
|
|
11417
|
+
this[objectProperty] instanceof Date &&
|
|
11418
|
+
this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
|
|
11419
|
+
) {
|
|
11420
|
+
return;
|
|
11421
|
+
}
|
|
11422
|
+
|
|
11423
|
+
if (dateFormatter.isValidDate(this[valueProperty])) {
|
|
11424
|
+
this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
|
|
11425
|
+
} else {
|
|
11426
|
+
this.setDateObjectProperty(objectProperty, undefined);
|
|
11427
|
+
}
|
|
11428
|
+
}
|
|
11429
|
+
|
|
11314
11430
|
/**
|
|
11315
11431
|
* Sets up IMasks and logic based on auto-formatting requirements.
|
|
11316
11432
|
* @private
|
|
11317
11433
|
* @returns {void}
|
|
11318
11434
|
*/
|
|
11319
11435
|
configureAutoFormatting() {
|
|
11320
|
-
//
|
|
11321
|
-
//
|
|
11322
|
-
//
|
|
11323
|
-
//
|
|
11436
|
+
// Re-entrancy guard. The patched-setter's synthetic input event (suppressed
|
|
11437
|
+
// by _configuringMask above) could otherwise trigger handleInput →
|
|
11438
|
+
// processCreditCard → configureAutoFormatting before the outer call's
|
|
11439
|
+
// set value has finished its alignCursor pass.
|
|
11324
11440
|
if (this._configuringMask) return;
|
|
11325
11441
|
this._configuringMask = true;
|
|
11326
11442
|
try {
|
|
11327
|
-
// Destroy any prior mask so IMask can attach fresh under the new format.
|
|
11328
11443
|
if (this.maskInstance) {
|
|
11329
11444
|
this.maskInstance.destroy();
|
|
11330
11445
|
}
|
|
11331
11446
|
|
|
11447
|
+
// Pass new format to util
|
|
11332
11448
|
this.util.updateFormat(this.format);
|
|
11333
11449
|
|
|
11334
11450
|
const maskOptions = this.util.getMaskOptions(this.type, this.format);
|
|
11335
11451
|
|
|
11336
11452
|
if (this.inputElement && maskOptions.mask) {
|
|
11337
|
-
// Capture the current display so it can be re-applied after IMask
|
|
11338
|
-
// attaches. The restore at the bottom goes through maskInstance.value
|
|
11339
|
-
// (not inputElement.value directly) so the mask's internal state and
|
|
11340
|
-
// the input's displayed text stay in lock-step.
|
|
11341
|
-
let existingValue = this.inputElement.value;
|
|
11342
11453
|
|
|
11343
|
-
//
|
|
11344
|
-
//
|
|
11345
|
-
//
|
|
11346
|
-
//
|
|
11454
|
+
// Stash and clear any existing value before IMask init.
|
|
11455
|
+
// IMask's constructor processes the current input value which requires
|
|
11456
|
+
// selection state — clearing first avoids that scenario entirely.
|
|
11457
|
+
// When the format changes (e.g. locale switch) and we have a valid ISO
|
|
11458
|
+
// model value, compute the display string for the NEW format instead of
|
|
11459
|
+
// re-using the old display string, which may be invalid in the new mask.
|
|
11460
|
+
let existingValue = this.inputElement.value;
|
|
11347
11461
|
if (
|
|
11348
11462
|
this.util.isFullDateFormat(this.type, this.format) &&
|
|
11349
11463
|
this.value &&
|
|
11350
|
-
this.
|
|
11464
|
+
dateFormatter.isValidDate(this.value) &&
|
|
11465
|
+
this.valueObject instanceof Date &&
|
|
11466
|
+
!Number.isNaN(this.valueObject.getTime()) &&
|
|
11351
11467
|
typeof maskOptions.format === 'function'
|
|
11352
11468
|
) {
|
|
11353
11469
|
existingValue = maskOptions.format(this.valueObject);
|
|
11354
11470
|
}
|
|
11355
11471
|
|
|
11356
|
-
// Clear before IMask attaches so the constructor seeds an empty
|
|
11357
|
-
// internal value. Otherwise IMask reads the stale unmasked string
|
|
11358
|
-
// and emits a spurious 'accept' before the restore below runs.
|
|
11359
11472
|
this.skipNextProgrammaticInputEvent = true;
|
|
11360
11473
|
this.inputElement.value = '';
|
|
11361
11474
|
|
|
11362
11475
|
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
11363
11476
|
|
|
11364
|
-
// Mask fires 'accept' on every value change, including the restore
|
|
11365
|
-
// step below. Skip events fired during configureAutoFormatting so
|
|
11366
|
-
// we don't overwrite a value the parent just pushed.
|
|
11367
11477
|
this.maskInstance.on('accept', () => {
|
|
11478
|
+
// Suppress propagation during configureAutoFormatting's own value-restoration
|
|
11479
|
+
// (line below) — the mask emits 'accept' on every value-set, including ours,
|
|
11480
|
+
// and we don't want to overwrite a value the parent just pushed.
|
|
11368
11481
|
if (this._configuringMask) return;
|
|
11369
11482
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
11370
11483
|
if (this.type === "date") {
|
|
@@ -11372,8 +11485,6 @@ class BaseInput extends AuroElement {
|
|
|
11372
11485
|
}
|
|
11373
11486
|
});
|
|
11374
11487
|
|
|
11375
|
-
// Mask fires 'complete' on the restore step below for any value that
|
|
11376
|
-
// happens to be a complete match. Same setup-suppression as 'accept'.
|
|
11377
11488
|
this.maskInstance.on('complete', () => {
|
|
11378
11489
|
if (this._configuringMask) return;
|
|
11379
11490
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
@@ -11382,9 +11493,7 @@ class BaseInput extends AuroElement {
|
|
|
11382
11493
|
}
|
|
11383
11494
|
});
|
|
11384
11495
|
|
|
11385
|
-
//
|
|
11386
|
-
// the mask reformats it under the new rules and keeps its internal
|
|
11387
|
-
// _value aligned with the input's displayed text.
|
|
11496
|
+
// Restore the stashed value through IMask so it's properly masked
|
|
11388
11497
|
if (existingValue) {
|
|
11389
11498
|
this.maskInstance.value = existingValue;
|
|
11390
11499
|
}
|
|
@@ -11552,6 +11661,7 @@ class BaseInput extends AuroElement {
|
|
|
11552
11661
|
*/
|
|
11553
11662
|
reset() {
|
|
11554
11663
|
this.value = undefined;
|
|
11664
|
+
this.setDateObjectProperty('valueObject', undefined);
|
|
11555
11665
|
this.validation.reset(this);
|
|
11556
11666
|
}
|
|
11557
11667
|
|
|
@@ -11560,6 +11670,7 @@ class BaseInput extends AuroElement {
|
|
|
11560
11670
|
*/
|
|
11561
11671
|
clear() {
|
|
11562
11672
|
this.value = undefined;
|
|
11673
|
+
this.setDateObjectProperty('valueObject', undefined);
|
|
11563
11674
|
}
|
|
11564
11675
|
|
|
11565
11676
|
/**
|
|
@@ -12088,7 +12199,7 @@ class AuroHelpText extends LitElement {
|
|
|
12088
12199
|
}
|
|
12089
12200
|
}
|
|
12090
12201
|
|
|
12091
|
-
var formkitVersion = '
|
|
12202
|
+
var formkitVersion = '202606192121';
|
|
12092
12203
|
|
|
12093
12204
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
12094
12205
|
// See LICENSE in the project root for license information.
|
|
@@ -10331,7 +10331,6 @@ class AuroInputUtilities {
|
|
|
10331
10331
|
const maskOptions = this.getMaskOptions('date', normalizedFormat);
|
|
10332
10332
|
|
|
10333
10333
|
if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
|
|
10334
|
-
console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
|
|
10335
10334
|
return undefined;
|
|
10336
10335
|
}
|
|
10337
10336
|
|
|
@@ -10483,8 +10482,10 @@ class BaseInput extends AuroElement {
|
|
|
10483
10482
|
this.layout = 'classic';
|
|
10484
10483
|
this.locale = 'en-US';
|
|
10485
10484
|
this.max = undefined;
|
|
10485
|
+
this._maxObject = undefined;
|
|
10486
10486
|
this.maxLength = undefined;
|
|
10487
10487
|
this.min = undefined;
|
|
10488
|
+
this._minObject = undefined;
|
|
10488
10489
|
this.minLength = undefined;
|
|
10489
10490
|
this.required = false;
|
|
10490
10491
|
this.onDark = false;
|
|
@@ -10492,6 +10493,7 @@ class BaseInput extends AuroElement {
|
|
|
10492
10493
|
this.size = 'lg';
|
|
10493
10494
|
this.shape = 'classic';
|
|
10494
10495
|
this.value = undefined;
|
|
10496
|
+
this._valueObject = undefined;
|
|
10495
10497
|
|
|
10496
10498
|
this._initializePrivateDefaults();
|
|
10497
10499
|
}
|
|
@@ -11031,7 +11033,7 @@ class BaseInput extends AuroElement {
|
|
|
11031
11033
|
* @returns {Date|undefined}
|
|
11032
11034
|
*/
|
|
11033
11035
|
get valueObject() {
|
|
11034
|
-
return this.
|
|
11036
|
+
return this._valueObject || this._computeDateObjectFallback(this.value);
|
|
11035
11037
|
}
|
|
11036
11038
|
|
|
11037
11039
|
/**
|
|
@@ -11039,7 +11041,7 @@ class BaseInput extends AuroElement {
|
|
|
11039
11041
|
* @returns {Date|undefined}
|
|
11040
11042
|
*/
|
|
11041
11043
|
get minObject() {
|
|
11042
|
-
return this.
|
|
11044
|
+
return this._minObject || this._computeDateObjectFallback(this.min);
|
|
11043
11045
|
}
|
|
11044
11046
|
|
|
11045
11047
|
/**
|
|
@@ -11047,7 +11049,50 @@ class BaseInput extends AuroElement {
|
|
|
11047
11049
|
* @returns {Date|undefined}
|
|
11048
11050
|
*/
|
|
11049
11051
|
get maxObject() {
|
|
11050
|
-
return this.
|
|
11052
|
+
return this._maxObject || this._computeDateObjectFallback(this.max);
|
|
11053
|
+
}
|
|
11054
|
+
|
|
11055
|
+
/**
|
|
11056
|
+
* Parses a date string into a Date object when the corresponding `_*Object`
|
|
11057
|
+
* field hasn't been synced yet by `updated()`. Returns undefined when the
|
|
11058
|
+
* input type/format isn't a full date or the string is not a valid date.
|
|
11059
|
+
*
|
|
11060
|
+
* Why this exists: a parent (datepicker) can call `inputN.validate()` from
|
|
11061
|
+
* inside its own `updated()` before this input's `updated()` has run
|
|
11062
|
+
* `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
|
|
11063
|
+
* and range checks would otherwise silently no-op (flipping the result to
|
|
11064
|
+
* `valid` or `patternMismatch`).
|
|
11065
|
+
* @private
|
|
11066
|
+
* @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
|
|
11067
|
+
* @returns {Date|undefined}
|
|
11068
|
+
*/
|
|
11069
|
+
_computeDateObjectFallback(dateStr) {
|
|
11070
|
+
if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
|
|
11071
|
+
return undefined;
|
|
11072
|
+
}
|
|
11073
|
+
if (!dateFormatter.isValidDate(dateStr)) {
|
|
11074
|
+
return undefined;
|
|
11075
|
+
}
|
|
11076
|
+
return dateFormatter.stringToDateInstance(dateStr);
|
|
11077
|
+
}
|
|
11078
|
+
|
|
11079
|
+
/**
|
|
11080
|
+
* Internal setter for readonly date object properties.
|
|
11081
|
+
* @private
|
|
11082
|
+
* @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
|
|
11083
|
+
* @param {Date|undefined} propertyValue - Value to assign.
|
|
11084
|
+
* @returns {void}
|
|
11085
|
+
*/
|
|
11086
|
+
setDateObjectProperty(propertyName, propertyValue) {
|
|
11087
|
+
const internalPropertyName = `_${propertyName}`;
|
|
11088
|
+
const previousValue = this[internalPropertyName];
|
|
11089
|
+
|
|
11090
|
+
if (previousValue === propertyValue) {
|
|
11091
|
+
return;
|
|
11092
|
+
}
|
|
11093
|
+
|
|
11094
|
+
this[internalPropertyName] = propertyValue;
|
|
11095
|
+
this.requestUpdate(propertyName, previousValue);
|
|
11051
11096
|
}
|
|
11052
11097
|
|
|
11053
11098
|
connectedCallback() {
|
|
@@ -11076,6 +11121,7 @@ class BaseInput extends AuroElement {
|
|
|
11076
11121
|
format: this.format
|
|
11077
11122
|
});
|
|
11078
11123
|
this.configureDataForType();
|
|
11124
|
+
this.syncDateValues();
|
|
11079
11125
|
}
|
|
11080
11126
|
|
|
11081
11127
|
disconnectedCallback() {
|
|
@@ -11095,6 +11141,10 @@ class BaseInput extends AuroElement {
|
|
|
11095
11141
|
this.wrapperElement.addEventListener('click', this.handleClick);
|
|
11096
11142
|
}
|
|
11097
11143
|
|
|
11144
|
+
// add attribute for query selectors when auro-input is registered under a custom name
|
|
11145
|
+
if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
|
|
11146
|
+
this.setAttribute('auro-input', '');
|
|
11147
|
+
}
|
|
11098
11148
|
this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
|
|
11099
11149
|
|
|
11100
11150
|
// use validity message override if declared when initializing the component
|
|
@@ -11105,6 +11155,7 @@ class BaseInput extends AuroElement {
|
|
|
11105
11155
|
this.setCustomHelpTextMessage();
|
|
11106
11156
|
this.configureAutoFormatting();
|
|
11107
11157
|
this.configureDataForType();
|
|
11158
|
+
this.syncDateValues();
|
|
11108
11159
|
}
|
|
11109
11160
|
|
|
11110
11161
|
/**
|
|
@@ -11241,6 +11292,8 @@ class BaseInput extends AuroElement {
|
|
|
11241
11292
|
this.configureDataForType();
|
|
11242
11293
|
}
|
|
11243
11294
|
|
|
11295
|
+
this.syncDateValues(changedProperties);
|
|
11296
|
+
|
|
11244
11297
|
if (changedProperties.has('value')) {
|
|
11245
11298
|
if (this.value && this.value.length > 0) {
|
|
11246
11299
|
this.hasValue = true;
|
|
@@ -11262,14 +11315,14 @@ class BaseInput extends AuroElement {
|
|
|
11262
11315
|
|
|
11263
11316
|
if (formattedValue !== this.inputElement.value) {
|
|
11264
11317
|
this.skipNextProgrammaticInputEvent = true;
|
|
11265
|
-
if (this.maskInstance && this.type
|
|
11318
|
+
if (this.maskInstance && this.type === 'credit-card') {
|
|
11266
11319
|
// Route through the mask so its _value and el.value stay in lock-step
|
|
11267
11320
|
// (set value calls updateControl which writes el.value = displayValue).
|
|
11268
11321
|
// Writing el.value directly leaves the mask thinking displayValue is
|
|
11269
|
-
// stale; _saveSelection on the next focus/click then warns.
|
|
11270
|
-
//
|
|
11271
|
-
//
|
|
11272
|
-
// flip validity from patternMismatch to tooShort.
|
|
11322
|
+
// stale; _saveSelection on the next focus/click then warns. Scoped to
|
|
11323
|
+
// credit-card so date's own formattedValue (raw ISO when calendar-invalid)
|
|
11324
|
+
// isn't re-masked through the mm/dd/yyyy mask, which would truncate it
|
|
11325
|
+
// and flip validity from patternMismatch to tooShort.
|
|
11273
11326
|
this.maskInstance.value = formattedValue || '';
|
|
11274
11327
|
} else if (formattedValue) {
|
|
11275
11328
|
this.inputElement.value = formattedValue;
|
|
@@ -11311,60 +11364,120 @@ class BaseInput extends AuroElement {
|
|
|
11311
11364
|
}));
|
|
11312
11365
|
}
|
|
11313
11366
|
|
|
11367
|
+
|
|
11368
|
+
/**
|
|
11369
|
+
* Synchronizes the ISO string values and Date object representations for date-related properties.
|
|
11370
|
+
* This keeps the model and display values aligned when either side changes.
|
|
11371
|
+
*
|
|
11372
|
+
* When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
|
|
11373
|
+
* Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
|
|
11374
|
+
* represents a full year/month/day date format.
|
|
11375
|
+
*
|
|
11376
|
+
* @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
|
|
11377
|
+
* @returns {void}
|
|
11378
|
+
* @private
|
|
11379
|
+
*/
|
|
11380
|
+
syncDateValues(changedProperties = undefined) {
|
|
11381
|
+
if (!this.util.isFullDateFormat(this.type, this.format)) {
|
|
11382
|
+
return;
|
|
11383
|
+
}
|
|
11384
|
+
|
|
11385
|
+
this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
|
|
11386
|
+
this.syncSingleDateValue(changedProperties, 'minObject', 'min');
|
|
11387
|
+
this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
|
|
11388
|
+
}
|
|
11389
|
+
|
|
11390
|
+
/**
|
|
11391
|
+
* Synchronizes one date object/string property pair.
|
|
11392
|
+
* @private
|
|
11393
|
+
* @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
|
|
11394
|
+
* @param {string} objectProperty - Date object property name.
|
|
11395
|
+
* @param {string} valueProperty - ISO string property name.
|
|
11396
|
+
* @returns {void}
|
|
11397
|
+
*/
|
|
11398
|
+
syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
|
|
11399
|
+
const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
|
|
11400
|
+
|
|
11401
|
+
// objectProperty wins over valueProperty when both changed
|
|
11402
|
+
if (objectPropertyChanged && this[objectProperty]) {
|
|
11403
|
+
this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
|
|
11404
|
+
return;
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11407
|
+
const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
|
|
11408
|
+
if (!valuePropertyChanged) {
|
|
11409
|
+
return;
|
|
11410
|
+
}
|
|
11411
|
+
|
|
11412
|
+
// when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
|
|
11413
|
+
if (
|
|
11414
|
+
changedProperties &&
|
|
11415
|
+
valueProperty === 'value' &&
|
|
11416
|
+
changedProperties.get('value') === undefined &&
|
|
11417
|
+
this[objectProperty] instanceof Date &&
|
|
11418
|
+
this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
|
|
11419
|
+
) {
|
|
11420
|
+
return;
|
|
11421
|
+
}
|
|
11422
|
+
|
|
11423
|
+
if (dateFormatter.isValidDate(this[valueProperty])) {
|
|
11424
|
+
this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
|
|
11425
|
+
} else {
|
|
11426
|
+
this.setDateObjectProperty(objectProperty, undefined);
|
|
11427
|
+
}
|
|
11428
|
+
}
|
|
11429
|
+
|
|
11314
11430
|
/**
|
|
11315
11431
|
* Sets up IMasks and logic based on auto-formatting requirements.
|
|
11316
11432
|
* @private
|
|
11317
11433
|
* @returns {void}
|
|
11318
11434
|
*/
|
|
11319
11435
|
configureAutoFormatting() {
|
|
11320
|
-
//
|
|
11321
|
-
//
|
|
11322
|
-
//
|
|
11323
|
-
//
|
|
11436
|
+
// Re-entrancy guard. The patched-setter's synthetic input event (suppressed
|
|
11437
|
+
// by _configuringMask above) could otherwise trigger handleInput →
|
|
11438
|
+
// processCreditCard → configureAutoFormatting before the outer call's
|
|
11439
|
+
// set value has finished its alignCursor pass.
|
|
11324
11440
|
if (this._configuringMask) return;
|
|
11325
11441
|
this._configuringMask = true;
|
|
11326
11442
|
try {
|
|
11327
|
-
// Destroy any prior mask so IMask can attach fresh under the new format.
|
|
11328
11443
|
if (this.maskInstance) {
|
|
11329
11444
|
this.maskInstance.destroy();
|
|
11330
11445
|
}
|
|
11331
11446
|
|
|
11447
|
+
// Pass new format to util
|
|
11332
11448
|
this.util.updateFormat(this.format);
|
|
11333
11449
|
|
|
11334
11450
|
const maskOptions = this.util.getMaskOptions(this.type, this.format);
|
|
11335
11451
|
|
|
11336
11452
|
if (this.inputElement && maskOptions.mask) {
|
|
11337
|
-
// Capture the current display so it can be re-applied after IMask
|
|
11338
|
-
// attaches. The restore at the bottom goes through maskInstance.value
|
|
11339
|
-
// (not inputElement.value directly) so the mask's internal state and
|
|
11340
|
-
// the input's displayed text stay in lock-step.
|
|
11341
|
-
let existingValue = this.inputElement.value;
|
|
11342
11453
|
|
|
11343
|
-
//
|
|
11344
|
-
//
|
|
11345
|
-
//
|
|
11346
|
-
//
|
|
11454
|
+
// Stash and clear any existing value before IMask init.
|
|
11455
|
+
// IMask's constructor processes the current input value which requires
|
|
11456
|
+
// selection state — clearing first avoids that scenario entirely.
|
|
11457
|
+
// When the format changes (e.g. locale switch) and we have a valid ISO
|
|
11458
|
+
// model value, compute the display string for the NEW format instead of
|
|
11459
|
+
// re-using the old display string, which may be invalid in the new mask.
|
|
11460
|
+
let existingValue = this.inputElement.value;
|
|
11347
11461
|
if (
|
|
11348
11462
|
this.util.isFullDateFormat(this.type, this.format) &&
|
|
11349
11463
|
this.value &&
|
|
11350
|
-
this.
|
|
11464
|
+
dateFormatter.isValidDate(this.value) &&
|
|
11465
|
+
this.valueObject instanceof Date &&
|
|
11466
|
+
!Number.isNaN(this.valueObject.getTime()) &&
|
|
11351
11467
|
typeof maskOptions.format === 'function'
|
|
11352
11468
|
) {
|
|
11353
11469
|
existingValue = maskOptions.format(this.valueObject);
|
|
11354
11470
|
}
|
|
11355
11471
|
|
|
11356
|
-
// Clear before IMask attaches so the constructor seeds an empty
|
|
11357
|
-
// internal value. Otherwise IMask reads the stale unmasked string
|
|
11358
|
-
// and emits a spurious 'accept' before the restore below runs.
|
|
11359
11472
|
this.skipNextProgrammaticInputEvent = true;
|
|
11360
11473
|
this.inputElement.value = '';
|
|
11361
11474
|
|
|
11362
11475
|
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
11363
11476
|
|
|
11364
|
-
// Mask fires 'accept' on every value change, including the restore
|
|
11365
|
-
// step below. Skip events fired during configureAutoFormatting so
|
|
11366
|
-
// we don't overwrite a value the parent just pushed.
|
|
11367
11477
|
this.maskInstance.on('accept', () => {
|
|
11478
|
+
// Suppress propagation during configureAutoFormatting's own value-restoration
|
|
11479
|
+
// (line below) — the mask emits 'accept' on every value-set, including ours,
|
|
11480
|
+
// and we don't want to overwrite a value the parent just pushed.
|
|
11368
11481
|
if (this._configuringMask) return;
|
|
11369
11482
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
11370
11483
|
if (this.type === "date") {
|
|
@@ -11372,8 +11485,6 @@ class BaseInput extends AuroElement {
|
|
|
11372
11485
|
}
|
|
11373
11486
|
});
|
|
11374
11487
|
|
|
11375
|
-
// Mask fires 'complete' on the restore step below for any value that
|
|
11376
|
-
// happens to be a complete match. Same setup-suppression as 'accept'.
|
|
11377
11488
|
this.maskInstance.on('complete', () => {
|
|
11378
11489
|
if (this._configuringMask) return;
|
|
11379
11490
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
@@ -11382,9 +11493,7 @@ class BaseInput extends AuroElement {
|
|
|
11382
11493
|
}
|
|
11383
11494
|
});
|
|
11384
11495
|
|
|
11385
|
-
//
|
|
11386
|
-
// the mask reformats it under the new rules and keeps its internal
|
|
11387
|
-
// _value aligned with the input's displayed text.
|
|
11496
|
+
// Restore the stashed value through IMask so it's properly masked
|
|
11388
11497
|
if (existingValue) {
|
|
11389
11498
|
this.maskInstance.value = existingValue;
|
|
11390
11499
|
}
|
|
@@ -11552,6 +11661,7 @@ class BaseInput extends AuroElement {
|
|
|
11552
11661
|
*/
|
|
11553
11662
|
reset() {
|
|
11554
11663
|
this.value = undefined;
|
|
11664
|
+
this.setDateObjectProperty('valueObject', undefined);
|
|
11555
11665
|
this.validation.reset(this);
|
|
11556
11666
|
}
|
|
11557
11667
|
|
|
@@ -11560,6 +11670,7 @@ class BaseInput extends AuroElement {
|
|
|
11560
11670
|
*/
|
|
11561
11671
|
clear() {
|
|
11562
11672
|
this.value = undefined;
|
|
11673
|
+
this.setDateObjectProperty('valueObject', undefined);
|
|
11563
11674
|
}
|
|
11564
11675
|
|
|
11565
11676
|
/**
|
|
@@ -12088,7 +12199,7 @@ class AuroHelpText extends LitElement {
|
|
|
12088
12199
|
}
|
|
12089
12200
|
}
|
|
12090
12201
|
|
|
12091
|
-
var formkitVersion = '
|
|
12202
|
+
var formkitVersion = '202606192121';
|
|
12092
12203
|
|
|
12093
12204
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
12094
12205
|
// See LICENSE in the project root for license information.
|