@mgdis/mg-components 6.26.0 → 6.28.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/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mg-action-more_36.cjs.entry.js +506 -161
- package/dist/cjs/mg-components.cjs.js +1 -1
- package/dist/cjs/mg-illustration.cjs.entry.js +1 -1
- package/dist/cjs/mg-input-combobox.cjs.entry.js +60 -8
- package/dist/cjs/mg-input-file.cjs.entry.js +26 -3
- package/dist/cjs/mg-input-rich-text-editor.cjs.entry.js +2304 -1131
- package/dist/cjs/mg-loader.cjs.entry.js +1 -1
- package/dist/cjs/mg-progress.cjs.entry.js +1 -1
- package/dist/collection/assets/illustrations/index.js +1 -1
- package/dist/collection/assets/jodit/jodit.css +14 -1
- package/dist/collection/components/atoms/mg-button/mg-button.js +86 -13
- package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.js +103 -55
- package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +25 -4
- package/dist/collection/components/molecules/inputs/mg-input-combobox/mg-input-combobox.js +59 -7
- package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +25 -9
- package/dist/collection/components/molecules/inputs/mg-input-file/mg-input-file.js +25 -2
- package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.js +24 -6
- package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +24 -5
- package/dist/collection/components/molecules/inputs/mg-input-radio/mg-input-radio.js +64 -16
- package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +32 -10
- package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.js +24 -5
- package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.js +24 -6
- package/dist/collection/components/molecules/mg-details/mg-details.js +5 -1
- package/dist/collection/components/molecules/mg-form/mg-form.js +83 -9
- package/dist/collection/components/molecules/mg-illustrated-message/mg-illustrated-message.js +1 -1
- package/dist/collection/components/molecules/mg-loader/mg-loader.js +1 -1
- package/dist/collection/components/molecules/mg-message/mg-message.js +3 -3
- package/dist/collection/components/molecules/mg-modal/mg-modal.js +2 -2
- package/dist/collection/components/molecules/mg-panel/mg-panel.js +1 -1
- package/dist/collection/components/molecules/mg-popover/mg-popover-content/mg-popover-content.js +1 -1
- package/dist/collection/components/molecules/mg-popover/mg-popover.js +1 -1
- package/dist/collection/components/molecules/mg-progress/mg-progress.js +1 -1
- package/dist/collection/components/molecules/mg-skip-links/mg-skip-links.js +1 -1
- package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +1 -1
- package/dist/components/mg-button2.js +1 -1
- package/dist/components/mg-details.js +1 -1
- package/dist/components/mg-form.js +1 -1
- package/dist/components/mg-illustrated-message.js +1 -1
- package/dist/components/mg-illustration.js +1 -1
- package/dist/components/mg-input-checkbox.js +1 -1
- package/dist/components/mg-input-combobox.js +1 -1
- package/dist/components/mg-input-date.js +1 -1
- package/dist/components/mg-input-file.js +1 -1
- package/dist/components/mg-input-numeric.js +1 -1
- package/dist/components/mg-input-password.js +1 -1
- package/dist/components/mg-input-radio.js +1 -1
- package/dist/components/mg-input-rich-text-editor.js +285 -285
- package/dist/components/mg-input-select2.js +1 -1
- package/dist/components/mg-input-text2.js +1 -1
- package/dist/components/mg-input-textarea.js +1 -1
- package/dist/components/mg-input-toggle.js +1 -1
- package/dist/components/mg-input2.js +1 -1
- package/dist/components/mg-loader2.js +1 -1
- package/dist/components/mg-menu-item2.js +1 -1
- package/dist/components/mg-message2.js +1 -1
- package/dist/components/mg-modal.js +1 -1
- package/dist/components/mg-panel.js +1 -1
- package/dist/components/mg-popover-content2.js +1 -1
- package/dist/components/mg-popover2.js +1 -1
- package/dist/components/mg-progress.js +1 -1
- package/dist/components/mg-skip-links.js +1 -1
- package/dist/components/mg-tabs2.js +1 -1
- package/dist/components/mg-tooltip2.js +1 -1
- package/dist/custom-elements.json +12 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mg-action-more_36.entry.js +507 -162
- package/dist/esm/mg-components.js +1 -1
- package/dist/esm/mg-illustration.entry.js +1 -1
- package/dist/esm/mg-input-combobox.entry.js +60 -8
- package/dist/esm/mg-input-file.entry.js +26 -3
- package/dist/esm/mg-input-rich-text-editor.entry.js +2304 -1131
- package/dist/esm/mg-loader.entry.js +1 -1
- package/dist/esm/mg-progress.entry.js +1 -1
- package/dist/mg-components/mg-components.esm.js +1 -1
- package/dist/mg-components/p-2198f145.entry.js +1 -0
- package/dist/mg-components/p-85ebacd6.entry.js +1 -0
- package/dist/mg-components/{p-96fc508e.entry.js → p-c2beff2c.entry.js} +1 -1
- package/dist/mg-components/p-d4a4eb78.entry.js +1 -0
- package/dist/mg-components/p-e8b5e8d8.entry.js +1667 -0
- package/dist/mg-components/p-f308e2e4.entry.js +1 -0
- package/dist/mg-components/p-fdcce8d5.entry.js +1 -0
- package/dist/types/components/atoms/mg-button/mg-button.d.ts +41 -2
- package/dist/types/components/atoms/mg-tooltip/mg-tooltip.d.ts +33 -6
- package/dist/types/components/molecules/inputs/mg-input/mg-input.conf.d.ts +1 -0
- package/dist/types/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-combobox/mg-input-combobox.d.ts +21 -1
- package/dist/types/components/molecules/inputs/mg-input-date/mg-input-date.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-file/mg-input-file.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-numeric/mg-input-numeric.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-password/mg-input-password.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-radio/mg-input-radio.d.ts +29 -2
- package/dist/types/components/molecules/inputs/mg-input-select/mg-input-select.d.ts +10 -1
- package/dist/types/components/molecules/inputs/mg-input-text/mg-input-text.d.ts +9 -0
- package/dist/types/components/molecules/inputs/mg-input-textarea/mg-input-textarea.d.ts +9 -0
- package/dist/types/components/molecules/mg-form/mg-form.d.ts +22 -0
- package/dist/types/components.d.ts +10 -2
- package/ide/intellij/web-types.json +4 -4
- package/ide/vscode/html-custom-data.json +3 -3
- package/package.json +19 -19
- package/dist/mg-components/p-206505b5.entry.js +0 -1667
- package/dist/mg-components/p-3ad7441c.entry.js +0 -1
- package/dist/mg-components/p-5dff879a.entry.js +0 -1
- package/dist/mg-components/p-b20f3698.entry.js +0 -1
- package/dist/mg-components/p-bf2252c9.entry.js +0 -1
- package/dist/mg-components/p-f8e58181.entry.js +0 -1
|
@@ -9,6 +9,8 @@ export class MgInputDate {
|
|
|
9
9
|
constructor() {
|
|
10
10
|
// hasDisplayedError (triggered by blur event)
|
|
11
11
|
this.hasDisplayedError = false;
|
|
12
|
+
// raised when `value` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
13
|
+
this.validityCheckPending = false;
|
|
12
14
|
this.customErrorMessage = { lock: false };
|
|
13
15
|
/**
|
|
14
16
|
* Input name
|
|
@@ -80,10 +82,6 @@ export class MgInputDate {
|
|
|
80
82
|
* Handle input event
|
|
81
83
|
*/
|
|
82
84
|
this.handleInput = () => {
|
|
83
|
-
this.checkValidity();
|
|
84
|
-
if (this.hasDisplayedError) {
|
|
85
|
-
this.setErrorMessage();
|
|
86
|
-
}
|
|
87
85
|
this.value = this.input.value;
|
|
88
86
|
};
|
|
89
87
|
/**
|
|
@@ -105,11 +103,8 @@ export class MgInputDate {
|
|
|
105
103
|
// when we reset the field we need to test a blank value.
|
|
106
104
|
if (['Delete', 'Backspace'].includes(event.key)) {
|
|
107
105
|
event.preventDefault();
|
|
106
|
+
// validity is recomputed in componentDidUpdate, once the input actually holds the blank value
|
|
108
107
|
this.value = null;
|
|
109
|
-
this.checkValidity();
|
|
110
|
-
if (this.hasDisplayedError) {
|
|
111
|
-
this.setErrorMessage();
|
|
112
|
-
}
|
|
113
108
|
}
|
|
114
109
|
};
|
|
115
110
|
/**
|
|
@@ -196,6 +191,7 @@ export class MgInputDate {
|
|
|
196
191
|
};
|
|
197
192
|
}
|
|
198
193
|
validateValue(newValue) {
|
|
194
|
+
this.validityCheckPending = true;
|
|
199
195
|
// When the input is not fully completed or has been cleared, the value becomes an empty string.
|
|
200
196
|
if (['', undefined].includes(newValue)) {
|
|
201
197
|
// need to force value update to `null` to prevent extra render
|
|
@@ -288,6 +284,8 @@ export class MgInputDate {
|
|
|
288
284
|
lock: valid ? false : errorMessageLock,
|
|
289
285
|
message: valid ? undefined : errorMessage,
|
|
290
286
|
};
|
|
287
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
288
|
+
this.validityCheckPending = false;
|
|
291
289
|
this.setValidity(valid);
|
|
292
290
|
this.setErrorMessage(true);
|
|
293
291
|
this.hasDisplayedError = this.invalid;
|
|
@@ -358,14 +356,32 @@ export class MgInputDate {
|
|
|
358
356
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
359
357
|
return setTimeout(() => {
|
|
360
358
|
this.checkValidity();
|
|
359
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
360
|
+
this.validityCheckPending = false;
|
|
361
361
|
}, 0);
|
|
362
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
365
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
366
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
367
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
368
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
369
|
+
*/
|
|
370
|
+
componentDidUpdate() {
|
|
371
|
+
if (this.validityCheckPending && this.input !== undefined) {
|
|
372
|
+
this.validityCheckPending = false;
|
|
373
|
+
this.checkValidity();
|
|
374
|
+
if (this.hasDisplayedError) {
|
|
375
|
+
this.setErrorMessage();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
363
379
|
/**
|
|
364
380
|
* Render
|
|
365
381
|
* @returns HTML Element
|
|
366
382
|
*/
|
|
367
383
|
render() {
|
|
368
|
-
return (h("mg-input", { key: '
|
|
384
|
+
return (h("mg-input", { key: '3d3f6910dde9c32bbf3d0c853e0c778380ed40fc', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === null ? 'label' : this.tooltipPosition, helpText: this.formatHelpText(this.helpText), errorMessage: this.errorMessage }, this.readonly ? (this.value && h("b", { class: "mg-c-input__readonly-value" }, localeDate(this.value, this.locale))) : (h("input", { type: "date", class: "mg-c-input__box", min: this.min, max: this.max, value: this.value, id: this.identifier, name: this.name, disabled: this.disabled, required: this.required, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, ref: (el) => {
|
|
369
385
|
if (el !== null)
|
|
370
386
|
this.input = el;
|
|
371
387
|
} }))));
|
|
@@ -12,6 +12,8 @@ export class MgInputFile {
|
|
|
12
12
|
constructor() {
|
|
13
13
|
// hasDisplayedError (triggered by blur event)
|
|
14
14
|
this.hasDisplayedError = false;
|
|
15
|
+
// raised when `value` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
16
|
+
this.validityCheckPending = false;
|
|
15
17
|
this.customErrorMessage = { lock: false };
|
|
16
18
|
/**
|
|
17
19
|
* Input name
|
|
@@ -172,6 +174,7 @@ export class MgInputFile {
|
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
176
|
watchValue(newValue) {
|
|
177
|
+
this.validityCheckPending = true;
|
|
175
178
|
if (allItemsAreString(newValue)) {
|
|
176
179
|
this.files = this.value.map((fileName) => new File([], fileName));
|
|
177
180
|
}
|
|
@@ -277,6 +280,8 @@ export class MgInputFile {
|
|
|
277
280
|
lock: valid ? false : errorMessageLock,
|
|
278
281
|
message: valid ? undefined : errorMessage,
|
|
279
282
|
};
|
|
283
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
284
|
+
this.validityCheckPending = false;
|
|
280
285
|
this.setValidity(valid);
|
|
281
286
|
this.setErrorMessage(true);
|
|
282
287
|
this.hasDisplayedError = this.invalid;
|
|
@@ -328,16 +333,34 @@ export class MgInputFile {
|
|
|
328
333
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
329
334
|
return setTimeout(() => {
|
|
330
335
|
this.checkValidity();
|
|
336
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
337
|
+
this.validityCheckPending = false;
|
|
331
338
|
}, 0);
|
|
332
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
342
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
343
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
344
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
345
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
346
|
+
*/
|
|
347
|
+
componentDidUpdate() {
|
|
348
|
+
if (this.validityCheckPending && this.inputElement !== undefined) {
|
|
349
|
+
this.validityCheckPending = false;
|
|
350
|
+
this.checkValidity();
|
|
351
|
+
if (this.hasDisplayedError) {
|
|
352
|
+
this.setErrorMessage();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
333
356
|
/**
|
|
334
357
|
* Render
|
|
335
358
|
* @returns HTML Element
|
|
336
359
|
*/
|
|
337
360
|
render() {
|
|
338
|
-
return (h("mg-input", { key: '
|
|
361
|
+
return (h("mg-input", { key: 'f1613e1105c1eea0c08624ffc270a74889d85ce0', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, h("div", { key: '23897ae896de9569ea68bf88e26f1349eb5bc909', class: "mg-c-input__file-container" }, h("input", { key: '0601a8af1c3f17331cb671184353b8b63a5f4fa8', name: this.name, id: this.identifier, class: "mg-u-visually-hidden", type: "file", multiple: this.multiple === true, capture: this.capture, accept: this.accept, disabled: this.disabled, required: this.files.length === 0 && this.required, onFocus: this.handleInputFocus, onBlur: this.handleInputBlur, onChange: this.handleInputChange, "aria-invalid": (this.invalid === true).toString(), ref: (el) => {
|
|
339
362
|
this.inputElement = el;
|
|
340
|
-
} }), h("mg-button", { key: '
|
|
363
|
+
} }), h("mg-button", { key: '5ac1076a443cc1a0bb2d7168b1d248d31faeedfd', variant: "secondary", class: "mg-c-input__file-button", type: "button", disabled: this.disabled, onClick: this.handleButtonClick, onBlur: this.handleButtonBlur, tabindex: "-1", ref: (el) => {
|
|
341
364
|
this.fileButtonElement = el;
|
|
342
365
|
} }, this.messages.input.file.browse), this.renderFiles())));
|
|
343
366
|
}
|
|
@@ -12,6 +12,8 @@ export class MgInputNumeric {
|
|
|
12
12
|
constructor() {
|
|
13
13
|
// hasDisplayedError (triggered by blur event)
|
|
14
14
|
this.hasDisplayedError = false;
|
|
15
|
+
// raised when `value` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
16
|
+
this.validityCheckPending = false;
|
|
15
17
|
this.customErrorMessage = { lock: false };
|
|
16
18
|
/**
|
|
17
19
|
* Input name
|
|
@@ -78,11 +80,6 @@ export class MgInputNumeric {
|
|
|
78
80
|
*/
|
|
79
81
|
this.handleInput = () => {
|
|
80
82
|
this.value = this.input.value;
|
|
81
|
-
// Check validity
|
|
82
|
-
this.checkValidity();
|
|
83
|
-
if (this.hasDisplayedError) {
|
|
84
|
-
this.setErrorMessage();
|
|
85
|
-
}
|
|
86
83
|
};
|
|
87
84
|
/**
|
|
88
85
|
* Handle focus event
|
|
@@ -232,6 +229,7 @@ export class MgInputNumeric {
|
|
|
232
229
|
}
|
|
233
230
|
validateValue(newValue) {
|
|
234
231
|
var _a;
|
|
232
|
+
this.validityCheckPending = true;
|
|
235
233
|
// has input value is always render as string we get a stringified value or a '' for nullish value, so we test string type
|
|
236
234
|
if (typeof newValue === 'string') {
|
|
237
235
|
// Check if integer value starts with '0' (leading zero)
|
|
@@ -352,6 +350,8 @@ export class MgInputNumeric {
|
|
|
352
350
|
lock: valid ? false : errorMessageLock,
|
|
353
351
|
message: valid ? undefined : errorMessage,
|
|
354
352
|
};
|
|
353
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
354
|
+
this.validityCheckPending = false;
|
|
355
355
|
this.setValidity(valid);
|
|
356
356
|
this.setErrorMessage(true);
|
|
357
357
|
this.hasDisplayedError = this.invalid;
|
|
@@ -464,14 +464,32 @@ export class MgInputNumeric {
|
|
|
464
464
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
465
465
|
return setTimeout(() => {
|
|
466
466
|
this.checkValidity();
|
|
467
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
468
|
+
this.validityCheckPending = false;
|
|
467
469
|
}, 0);
|
|
468
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
473
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
474
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
475
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
476
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
477
|
+
*/
|
|
478
|
+
componentDidUpdate() {
|
|
479
|
+
if (this.validityCheckPending && this.input !== undefined) {
|
|
480
|
+
this.validityCheckPending = false;
|
|
481
|
+
this.checkValidity();
|
|
482
|
+
if (this.hasDisplayedError) {
|
|
483
|
+
this.setErrorMessage();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
469
487
|
/**
|
|
470
488
|
* Render
|
|
471
489
|
* @returns HTML Element
|
|
472
490
|
*/
|
|
473
491
|
render() {
|
|
474
|
-
return (h("mg-input", { key: '
|
|
492
|
+
return (h("mg-input", { key: '8a9a2c269754aa1259e79dd5e68cc0ed6b578fd1', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.formatHelpText(this.helpText), errorMessage: this.errorMessage }, this.readonly
|
|
475
493
|
? this.readonlyValue && this.renderReadonly()
|
|
476
494
|
: [
|
|
477
495
|
h("input", { key: "input", type: "text", class: "mg-c-input__box mg-c-input__box--width", value: this.displayValue(), id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, autocomplete: "off", "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: (el) => {
|
|
@@ -8,6 +8,8 @@ export class MgInputPassword {
|
|
|
8
8
|
// hasDisplayedError (triggered by blur event)
|
|
9
9
|
this.hasDisplayedError = false;
|
|
10
10
|
this.customErrorMessage = { lock: false };
|
|
11
|
+
// raised when `value` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
12
|
+
this.validityCheckPending = false;
|
|
11
13
|
/**
|
|
12
14
|
* Input name
|
|
13
15
|
* If not set the value equals the identifier
|
|
@@ -53,10 +55,6 @@ export class MgInputPassword {
|
|
|
53
55
|
* Handle input event
|
|
54
56
|
*/
|
|
55
57
|
this.handleInput = () => {
|
|
56
|
-
this.checkValidity();
|
|
57
|
-
if (this.hasDisplayedError) {
|
|
58
|
-
this.setErrorMessage();
|
|
59
|
-
}
|
|
60
58
|
this.value = this.input.value;
|
|
61
59
|
};
|
|
62
60
|
/**
|
|
@@ -101,6 +99,7 @@ export class MgInputPassword {
|
|
|
101
99
|
};
|
|
102
100
|
}
|
|
103
101
|
handleValue(newValue) {
|
|
102
|
+
this.validityCheckPending = true;
|
|
104
103
|
this.valueChange.emit(newValue);
|
|
105
104
|
}
|
|
106
105
|
watchReadonly(newValue) {
|
|
@@ -181,6 +180,8 @@ export class MgInputPassword {
|
|
|
181
180
|
lock: valid ? false : errorMessageLock,
|
|
182
181
|
message: valid ? undefined : errorMessage,
|
|
183
182
|
};
|
|
183
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
184
|
+
this.validityCheckPending = false;
|
|
184
185
|
this.setValidity(valid);
|
|
185
186
|
this.setErrorMessage(true);
|
|
186
187
|
this.hasDisplayedError = this.invalid;
|
|
@@ -243,15 +244,33 @@ export class MgInputPassword {
|
|
|
243
244
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
244
245
|
return setTimeout(() => {
|
|
245
246
|
this.checkValidity();
|
|
247
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
248
|
+
this.validityCheckPending = false;
|
|
246
249
|
}, 0);
|
|
247
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
253
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
254
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
255
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
256
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
257
|
+
*/
|
|
258
|
+
componentDidUpdate() {
|
|
259
|
+
if (this.validityCheckPending && this.input !== undefined) {
|
|
260
|
+
this.validityCheckPending = false;
|
|
261
|
+
this.checkValidity();
|
|
262
|
+
if (this.hasDisplayedError) {
|
|
263
|
+
this.setErrorMessage();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
248
267
|
/**
|
|
249
268
|
* Render
|
|
250
269
|
* @returns HTML Element
|
|
251
270
|
*/
|
|
252
271
|
render() {
|
|
253
272
|
const displayPasswordIcon = this.displayPassword ? 'eye-slash' : 'eye';
|
|
254
|
-
return (h("mg-input", { key: '
|
|
273
|
+
return (h("mg-input", { key: '2d9498c380536dc32177d1ac16a513ee43944a72', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (this.value !== undefined && h("b", { class: "mg-c-input__readonly-value" }, '•'.repeat(this.value.length))) : (h("span", { class: "mg-c-input__input-group" }, h("input", { type: this.displayPassword ? 'text' : 'password', class: "mg-c-input__box mg-c-input__box--width", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, maxlength: this.maxlength, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
|
|
255
274
|
if (el !== null)
|
|
256
275
|
this.input = el;
|
|
257
276
|
} }), h("mg-button", { label: this.messages.input.password[this.displayPassword ? 'hide' : 'display'], disabled: this.disabled, variant: "flat", class: "mg-c-input__append-button", "is-icon": true, onClick: this.toggleDisplayPassword, "aria-controls": this.identifier }, h("mg-icon", { class: "mg-c-input__input-icon", icon: displayPasswordIcon }))))));
|
|
@@ -16,12 +16,12 @@ export class MgInputRadio {
|
|
|
16
16
|
/************
|
|
17
17
|
* Internal *
|
|
18
18
|
************/
|
|
19
|
-
// HTML selector
|
|
20
|
-
this.inputs = [];
|
|
21
19
|
// classes
|
|
22
20
|
this.classVerticalList = 'mg-c-input--vertical-list';
|
|
23
21
|
// hasDisplayedError (triggered by blur event)
|
|
24
22
|
this.hasDisplayedError = false;
|
|
23
|
+
// raised when `value` or `items` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
24
|
+
this.validityCheckPending = false;
|
|
25
25
|
this.customErrorMessage = { lock: false };
|
|
26
26
|
/**
|
|
27
27
|
* Input name
|
|
@@ -65,7 +65,6 @@ export class MgInputRadio {
|
|
|
65
65
|
* @param event - input event
|
|
66
66
|
*/
|
|
67
67
|
this.handleInput = (event) => {
|
|
68
|
-
this.checkValidity();
|
|
69
68
|
this.value = this.options[event.target.value].value;
|
|
70
69
|
};
|
|
71
70
|
/**
|
|
@@ -78,11 +77,23 @@ export class MgInputRadio {
|
|
|
78
77
|
// reset guard
|
|
79
78
|
this.handlerInProgress = undefined;
|
|
80
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Check if the required constraint is fulfilled
|
|
82
|
+
* The native group validity cannot answer it: a browser keeps the checked member a group had, even
|
|
83
|
+
* once that input is removed from the DOM. Options that cannot be selected are ignored.
|
|
84
|
+
* @returns required constraint is fulfilled
|
|
85
|
+
*/
|
|
86
|
+
this.validateRequired = () => {
|
|
87
|
+
const selectableOptions = this.options.filter((option) => !option.disabled);
|
|
88
|
+
return (!this.required ||
|
|
89
|
+
selectableOptions.length < 1 ||
|
|
90
|
+
selectableOptions.some((option) => this.isSelectedValue(option.value)));
|
|
91
|
+
};
|
|
81
92
|
/**
|
|
82
93
|
* Check if input is valid
|
|
83
94
|
*/
|
|
84
95
|
this.checkValidity = () => {
|
|
85
|
-
this.setValidity(this.readonly || this.disabled || this.getInvalidElement() === undefined);
|
|
96
|
+
this.setValidity(this.readonly || this.disabled || (this.getInvalidElement() === undefined && this.validateRequired()));
|
|
86
97
|
};
|
|
87
98
|
/**
|
|
88
99
|
* Set input error message
|
|
@@ -98,7 +109,7 @@ export class MgInputRadio {
|
|
|
98
109
|
this.errorMessage = this.customErrorMessage.message;
|
|
99
110
|
}
|
|
100
111
|
// required
|
|
101
|
-
else if (invalidElement.validity.valueMissing) {
|
|
112
|
+
else if (invalidElement === undefined || invalidElement.validity.valueMissing) {
|
|
102
113
|
this.errorMessage = this.messages.errors.required;
|
|
103
114
|
}
|
|
104
115
|
}
|
|
@@ -107,11 +118,24 @@ export class MgInputRadio {
|
|
|
107
118
|
* get invalid element
|
|
108
119
|
* @returns element
|
|
109
120
|
*/
|
|
110
|
-
this.getInvalidElement = () => this.
|
|
121
|
+
this.getInvalidElement = () => this.getInputs().find((input) => !input.disabled && !input.readOnly && !input.checkValidity());
|
|
122
|
+
/**
|
|
123
|
+
* Get the rendered radio inputs
|
|
124
|
+
* Read from the DOM: references kept from a render would outlive the inputs they point to.
|
|
125
|
+
* @returns rendered radio inputs
|
|
126
|
+
*/
|
|
127
|
+
this.getInputs = () => Array.from(this.element.shadowRoot.querySelectorAll('input[type="radio"]'));
|
|
128
|
+
/**
|
|
129
|
+
* Check if a value is the selected one
|
|
130
|
+
* @param optionValue - option value to compare to the component value
|
|
131
|
+
* @returns option value is the selected one
|
|
132
|
+
*/
|
|
133
|
+
this.isSelectedValue = (optionValue) => JSON.stringify(this.value) === JSON.stringify(optionValue);
|
|
111
134
|
}
|
|
112
135
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
136
|
watchValue(newValue) {
|
|
114
137
|
var _a;
|
|
138
|
+
this.validityCheckPending = true;
|
|
115
139
|
if (allItemsAreString(this.items) && typeof newValue === 'string') {
|
|
116
140
|
this.readonlyValue = newValue;
|
|
117
141
|
}
|
|
@@ -123,7 +147,7 @@ export class MgInputRadio {
|
|
|
123
147
|
}
|
|
124
148
|
this.valueChange.emit(newValue);
|
|
125
149
|
}
|
|
126
|
-
validateItems(newValue) {
|
|
150
|
+
validateItems(newValue, oldValue) {
|
|
127
151
|
// Validate if items have required min length
|
|
128
152
|
if (typeof newValue === 'object' && newValue.length < 2) {
|
|
129
153
|
throw new Error(`<mg-input-radio> prop "items" require at least 2 items. Passed value: ${toString(newValue)}.`);
|
|
@@ -139,6 +163,14 @@ export class MgInputRadio {
|
|
|
139
163
|
else {
|
|
140
164
|
throw new Error(`<mg-input-radio> prop "items" is required and all items must be the same type, string or RadioOption. Passed value: ${toString(newValue)}.`);
|
|
141
165
|
}
|
|
166
|
+
// `oldValue` is undefined on init
|
|
167
|
+
if (oldValue !== undefined) {
|
|
168
|
+
// the options cannot display a value they no longer offer, drop it
|
|
169
|
+
if (this.value !== undefined && !this.options.some((option) => this.isSelectedValue(option.value))) {
|
|
170
|
+
this.value = undefined;
|
|
171
|
+
}
|
|
172
|
+
this.validityCheckPending = true;
|
|
173
|
+
}
|
|
142
174
|
}
|
|
143
175
|
watchInputVerticalList(newValue) {
|
|
144
176
|
if (newValue)
|
|
@@ -153,7 +185,7 @@ export class MgInputRadio {
|
|
|
153
185
|
this.classCollection.delete(classReadonly);
|
|
154
186
|
}
|
|
155
187
|
handleValidityChange(newValue, _oldValue, prop) {
|
|
156
|
-
this.
|
|
188
|
+
this.getInputs().forEach((input) => {
|
|
157
189
|
input[prop] = newValue;
|
|
158
190
|
});
|
|
159
191
|
this.checkValidity();
|
|
@@ -172,9 +204,8 @@ export class MgInputRadio {
|
|
|
172
204
|
* Set focus on input.
|
|
173
205
|
*/
|
|
174
206
|
async setFocus() {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
207
|
+
var _a;
|
|
208
|
+
(_a = this.element.shadowRoot.querySelector('input')) === null || _a === void 0 ? void 0 : _a.focus();
|
|
178
209
|
}
|
|
179
210
|
/**
|
|
180
211
|
* Display input error if it exists.
|
|
@@ -216,6 +247,8 @@ export class MgInputRadio {
|
|
|
216
247
|
lock: valid ? false : errorMessageLock,
|
|
217
248
|
message: valid ? undefined : errorMessage,
|
|
218
249
|
};
|
|
250
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
251
|
+
this.validityCheckPending = false;
|
|
219
252
|
this.setValidity(valid);
|
|
220
253
|
this.setErrorMessage(true);
|
|
221
254
|
this.hasDisplayedError = this.invalid;
|
|
@@ -281,20 +314,35 @@ export class MgInputRadio {
|
|
|
281
314
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
282
315
|
return setTimeout(() => {
|
|
283
316
|
this.checkValidity();
|
|
317
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
318
|
+
this.validityCheckPending = false;
|
|
284
319
|
}, 0);
|
|
285
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
323
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
324
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
325
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
326
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
327
|
+
*/
|
|
328
|
+
componentDidUpdate() {
|
|
329
|
+
if (this.validityCheckPending && this.getInputs().length > 0) {
|
|
330
|
+
this.validityCheckPending = false;
|
|
331
|
+
this.checkValidity();
|
|
332
|
+
if (this.hasDisplayedError) {
|
|
333
|
+
this.setErrorMessage();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
286
337
|
/**
|
|
287
338
|
* Render
|
|
288
339
|
* @returns HTML Element
|
|
289
340
|
*/
|
|
290
341
|
render() {
|
|
291
|
-
return (h("mg-input", { key: '
|
|
342
|
+
return (h("mg-input", { key: '1fd4b600eb95f2ff5c753884c40b982e0552d576', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && !this.value ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (this.readonlyValue && h("b", { class: "mg-c-input__readonly-value" }, this.readonlyValue)) : (h("div", { class: "mg-c-input__input-group-container" }, this.options.map((input, index) => (h("div", { key: input.title, class: {
|
|
292
343
|
'mg-c-input__input-group': true,
|
|
293
344
|
'mg-c-input__input-group--disabled': this.disabled || input.disabled,
|
|
294
|
-
} }, h("input", { type: "radio", id: this.identifier + '_' + index, name: this.identifier, value: index, checked:
|
|
295
|
-
if (el !== null)
|
|
296
|
-
this.inputs[index] = el;
|
|
297
|
-
} }), h("label", { htmlFor: this.identifier + '_' + index }, input.title))))))));
|
|
345
|
+
} }, h("input", { type: "radio", id: this.identifier + '_' + index, name: this.identifier, value: index, checked: this.isSelectedValue(this.options[index].value), disabled: this.disabled || input.disabled, required: this.required, onBlur: this.handleBlur, onInput: this.handleInput }), h("label", { htmlFor: this.identifier + '_' + index }, input.title))))))));
|
|
298
346
|
}
|
|
299
347
|
static get is() { return "mg-input-radio"; }
|
|
300
348
|
static get encapsulation() { return "shadow"; }
|
|
@@ -24,8 +24,9 @@ const isOptGroup = (optgroup) => typeof optgroup === 'object' &&
|
|
|
24
24
|
typeof optgroup.group === 'string' &&
|
|
25
25
|
allItemsAreOptions(optgroup.options);
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Report, without enforcing, options that cannot be unambiguously differentiated by their title
|
|
28
28
|
* Two options can share the same title only when they belong to different groups
|
|
29
|
+
* An option is identified by its render index, so a duplicated title only harms readability: it is reported to the developer and the field still renders
|
|
29
30
|
* @param items - select options to validate
|
|
30
31
|
*/
|
|
31
32
|
const validateUniqueTitles = (items) => {
|
|
@@ -37,7 +38,7 @@ const validateUniqueTitles = (items) => {
|
|
|
37
38
|
const titles = titlesByGroup.get(group);
|
|
38
39
|
if (titles.has(title)) {
|
|
39
40
|
const groupContext = group === undefined ? 'outside of a group' : `within the group "${group}"`;
|
|
40
|
-
|
|
41
|
+
console.error(`<mg-input-select> prop "items" must not contain options with the same "title" ${groupContext}. Duplicated title: "${title}".`);
|
|
41
42
|
}
|
|
42
43
|
titles.add(title);
|
|
43
44
|
});
|
|
@@ -70,6 +71,8 @@ export class MgInputSelect {
|
|
|
70
71
|
constructor() {
|
|
71
72
|
// hasDisplayedError (triggered by blur event)
|
|
72
73
|
this.hasDisplayedError = false;
|
|
74
|
+
// raised when `value` or `items` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
75
|
+
this.validityCheckPending = false;
|
|
73
76
|
this.customErrorMessage = { lock: false };
|
|
74
77
|
/**
|
|
75
78
|
* Input name
|
|
@@ -217,18 +220,14 @@ export class MgInputSelect {
|
|
|
217
220
|
this.renderOption = (option, index) => (h("option", { key: index, value: `${index}`, selected: JSON.stringify(this.value) === JSON.stringify(option.value), disabled: option.disabled }, option.title));
|
|
218
221
|
}
|
|
219
222
|
validateValue(newValue) {
|
|
220
|
-
|
|
221
|
-
this.checkValidity();
|
|
222
|
-
if (this.hasDisplayedError) {
|
|
223
|
-
this.setErrorMessage();
|
|
224
|
-
}
|
|
225
|
-
}, 0);
|
|
223
|
+
this.validityCheckPending = true;
|
|
226
224
|
this.valueChange.emit(newValue);
|
|
227
225
|
}
|
|
228
|
-
validateItems(newValue) {
|
|
226
|
+
validateItems(newValue, oldValue) {
|
|
229
227
|
// Empty options
|
|
230
228
|
if (newValue.length === 0) {
|
|
231
229
|
this.options = [];
|
|
230
|
+
this.valueExist = false;
|
|
232
231
|
}
|
|
233
232
|
// String array
|
|
234
233
|
else if (allItemsAreString(newValue)) {
|
|
@@ -254,6 +253,9 @@ export class MgInputSelect {
|
|
|
254
253
|
else {
|
|
255
254
|
throw new Error(`<mg-input-select> prop "items" is required, can be an empty Array or all items must be the same type: string or Option. Passed value: ${toString(newValue)}.`);
|
|
256
255
|
}
|
|
256
|
+
// `oldValue` is undefined on init. The value is kept: an unmatched one renders the placeholder.
|
|
257
|
+
if (oldValue !== undefined)
|
|
258
|
+
this.validityCheckPending = true;
|
|
257
259
|
}
|
|
258
260
|
watchReadonly(newValue) {
|
|
259
261
|
if (newValue)
|
|
@@ -333,6 +335,8 @@ export class MgInputSelect {
|
|
|
333
335
|
lock: valid ? false : errorMessageLock,
|
|
334
336
|
message: valid ? undefined : errorMessage,
|
|
335
337
|
};
|
|
338
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
339
|
+
this.validityCheckPending = false;
|
|
336
340
|
this.setValidity(valid);
|
|
337
341
|
this.setErrorMessage(true);
|
|
338
342
|
this.hasDisplayedError = this.invalid;
|
|
@@ -403,8 +407,26 @@ export class MgInputSelect {
|
|
|
403
407
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
404
408
|
return setTimeout(() => {
|
|
405
409
|
this.checkValidity();
|
|
410
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
411
|
+
this.validityCheckPending = false;
|
|
406
412
|
}, 0);
|
|
407
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
416
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
417
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
418
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
419
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
420
|
+
*/
|
|
421
|
+
componentDidUpdate() {
|
|
422
|
+
if (this.validityCheckPending && this.input !== undefined) {
|
|
423
|
+
this.validityCheckPending = false;
|
|
424
|
+
this.checkValidity();
|
|
425
|
+
if (this.hasDisplayedError) {
|
|
426
|
+
this.setErrorMessage();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
408
430
|
/**
|
|
409
431
|
* Render
|
|
410
432
|
* @returns HTML Element
|
|
@@ -413,7 +435,7 @@ export class MgInputSelect {
|
|
|
413
435
|
const readonlyValue = this.getReadonlyValue();
|
|
414
436
|
// Running index shared across groups, so each option gets a unique value matching its position in getOptions()
|
|
415
437
|
let optionIndex = 0;
|
|
416
|
-
return (h("mg-input", { key: '
|
|
438
|
+
return (h("mg-input", { key: 'ca4a3a1b95094505bff8bf062566a633a1b12d1a', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && readonlyValue === null ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (readonlyValue && h("b", { class: "mg-c-input__readonly-value" }, readonlyValue)) : (h("select", { class: "mg-c-input__box", id: this.identifier, name: this.name, title: this.placeholder, disabled: this.disabled, required: this.required, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
|
|
417
439
|
if (el !== null)
|
|
418
440
|
this.input = el;
|
|
419
441
|
} }, (!this.placeholderHide || !this.valueExist) && ( // In case passed value does not match any option we display the placeholder
|
|
@@ -34,6 +34,8 @@ export class MgInputText {
|
|
|
34
34
|
// hasDisplayedError (triggered by blur event)
|
|
35
35
|
this.hasDisplayedError = false;
|
|
36
36
|
this.customErrorMessage = { lock: false };
|
|
37
|
+
// raised when `value` changed, so componentDidUpdate revalidates once the DOM is in sync
|
|
38
|
+
this.validityCheckPending = false;
|
|
37
39
|
/**
|
|
38
40
|
* Input name
|
|
39
41
|
* If not set the value equals the identifier
|
|
@@ -98,10 +100,6 @@ export class MgInputText {
|
|
|
98
100
|
* Handle input event
|
|
99
101
|
*/
|
|
100
102
|
this.handleInput = () => {
|
|
101
|
-
this.checkValidity();
|
|
102
|
-
if (this.hasDisplayedError) {
|
|
103
|
-
this.setErrorMessage();
|
|
104
|
-
}
|
|
105
103
|
this.value = this.input.value;
|
|
106
104
|
};
|
|
107
105
|
/**
|
|
@@ -182,6 +180,7 @@ export class MgInputText {
|
|
|
182
180
|
}
|
|
183
181
|
handleValue(newValue) {
|
|
184
182
|
var _a, _b;
|
|
183
|
+
this.validityCheckPending = true;
|
|
185
184
|
if ((_a = this.datalistoptions) === null || _a === void 0 ? void 0 : _a.every(isOption)) {
|
|
186
185
|
this.valueChange.emit(((_b = this.datalistoptions.find((option) => option.title === newValue)) === null || _b === void 0 ? void 0 : _b.value) || newValue);
|
|
187
186
|
}
|
|
@@ -301,6 +300,8 @@ export class MgInputText {
|
|
|
301
300
|
lock: valid ? false : errorMessageLock,
|
|
302
301
|
message: valid ? undefined : errorMessage,
|
|
303
302
|
};
|
|
303
|
+
// setError() states the validity explicitly, so drop any pending recomputation
|
|
304
|
+
this.validityCheckPending = false;
|
|
304
305
|
this.setValidity(valid);
|
|
305
306
|
this.setErrorMessage(true);
|
|
306
307
|
this.hasDisplayedError = this.invalid;
|
|
@@ -373,14 +374,32 @@ export class MgInputText {
|
|
|
373
374
|
// https://stenciljs.com/docs/component-lifecycle#componentwillload
|
|
374
375
|
return setTimeout(() => {
|
|
375
376
|
this.checkValidity();
|
|
377
|
+
// the initial check covers the initial value: nothing is pending yet
|
|
378
|
+
this.validityCheckPending = false;
|
|
376
379
|
}, 0);
|
|
377
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Recompute validity once the DOM is in sync with `value`.
|
|
383
|
+
* `@Watch('value')` fires before Stencil re-renders, so the rendered control still holds the
|
|
384
|
+
* previous value at that point (visible with a programmatic value change, e.g. a `v-model`
|
|
385
|
+
* default value). The watcher therefore only raises a flag, and the check runs here, after the
|
|
386
|
+
* render. Renders unrelated to `value` leave the flag down and recompute nothing.
|
|
387
|
+
*/
|
|
388
|
+
componentDidUpdate() {
|
|
389
|
+
if (this.validityCheckPending && this.input !== undefined) {
|
|
390
|
+
this.validityCheckPending = false;
|
|
391
|
+
this.checkValidity();
|
|
392
|
+
if (this.hasDisplayedError) {
|
|
393
|
+
this.setErrorMessage();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
378
397
|
/**
|
|
379
398
|
* Render
|
|
380
399
|
* @returns HTML Element
|
|
381
400
|
*/
|
|
382
401
|
render() {
|
|
383
|
-
return (h("mg-input", { key: '
|
|
402
|
+
return (h("mg-input", { key: '20a89d186c673936740cce348977cc0a8471fafb', label: this.label, identifier: this.identifier, class: this.classCollection.join(), ariaDescribedbyIDs: this.characterLeftId, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly
|
|
384
403
|
? this.value && this.renderReadonly()
|
|
385
404
|
: [
|
|
386
405
|
h("div", { key: "input", class: "mg-c-input__input-group-container", style: {
|