@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.
- package/components/checkbox/demo/customize.min.js +18 -10
- package/components/checkbox/demo/getting-started.min.js +18 -10
- package/components/checkbox/demo/index.min.js +18 -10
- package/components/checkbox/dist/index.js +18 -10
- package/components/checkbox/dist/registered.js +18 -10
- package/components/combobox/README.md +1 -1
- package/components/combobox/demo/customize.md +2 -10
- package/components/combobox/demo/customize.min.js +454 -467
- package/components/combobox/demo/getting-started.min.js +454 -463
- package/components/combobox/demo/index.md +1 -1
- package/components/combobox/demo/index.min.js +454 -463
- package/components/combobox/demo/keyboard-behavior.md +2 -142
- package/components/combobox/demo/readme.md +1 -1
- package/components/combobox/demo/why-combobox.md +2 -2
- package/components/combobox/dist/auro-combobox.d.ts +30 -14
- package/components/combobox/dist/index.js +454 -463
- package/components/combobox/dist/registered.js +454 -463
- package/components/counter/demo/customize.min.js +32 -12
- package/components/counter/demo/index.min.js +32 -12
- package/components/counter/dist/index.js +32 -12
- package/components/counter/dist/registered.js +32 -12
- package/components/datepicker/demo/customize.min.js +183 -167
- package/components/datepicker/demo/index.min.js +183 -167
- package/components/datepicker/dist/index.js +183 -167
- package/components/datepicker/dist/registered.js +183 -167
- package/components/dropdown/demo/customize.min.js +14 -2
- package/components/dropdown/demo/getting-started.min.js +14 -2
- package/components/dropdown/demo/index.min.js +14 -2
- package/components/dropdown/dist/index.js +14 -2
- package/components/dropdown/dist/registered.js +14 -2
- package/components/form/demo/customize.min.js +851 -829
- package/components/form/demo/getting-started.min.js +851 -829
- package/components/form/demo/index.min.js +851 -829
- package/components/form/demo/registerDemoDeps.min.js +851 -829
- package/components/input/demo/api.md +58 -57
- package/components/input/demo/customize.min.js +114 -155
- package/components/input/demo/getting-started.min.js +114 -155
- package/components/input/demo/index.min.js +114 -155
- package/components/input/dist/base-input.d.ts +9 -51
- package/components/input/dist/index.js +114 -155
- package/components/input/dist/registered.js +114 -155
- package/components/input/dist/utilities.d.ts +9 -0
- package/components/radio/demo/customize.min.js +18 -10
- package/components/radio/demo/getting-started.min.js +18 -10
- package/components/radio/demo/index.min.js +18 -10
- package/components/radio/dist/index.js +18 -10
- package/components/radio/dist/registered.js +18 -10
- package/components/select/demo/customize.min.js +32 -12
- package/components/select/demo/getting-started.min.js +32 -12
- package/components/select/demo/index.min.js +32 -12
- package/components/select/dist/index.js +32 -12
- package/components/select/dist/registered.js +32 -12
- package/custom-elements.json +142 -278
- 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.
|
|
4291
|
-
|
|
4292
|
-
|
|
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
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
11312
|
-
//
|
|
11313
|
-
//
|
|
11314
|
-
//
|
|
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
|
-
//
|
|
11426
|
-
//
|
|
11427
|
-
//
|
|
11428
|
-
//
|
|
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
|
-
//
|
|
11444
|
-
//
|
|
11445
|
-
//
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
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 = '
|
|
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.
|
|
721
|
-
|
|
722
|
-
|
|
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
|
-
|
|
817
|
-
|
|
818
|
-
|
|
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 = '
|
|
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.
|
|
721
|
-
|
|
722
|
-
|
|
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
|
-
|
|
817
|
-
|
|
818
|
-
|
|
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 = '
|
|
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.
|