@ionic/core 8.7.4-dev.11755800369.16c1f61b → 8.7.4-dev.11755809082.11a7702b
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/ion-input.js +16 -7
- package/components/ion-textarea.js +15 -6
- package/dist/cjs/ion-input.cjs.entry.js +16 -7
- package/dist/cjs/ion-textarea.cjs.entry.js +15 -6
- package/dist/collection/components/input/input.js +16 -7
- package/dist/collection/components/textarea/textarea.js +15 -6
- package/dist/docs.json +1 -1
- package/dist/esm/ion-input.entry.js +16 -7
- package/dist/esm/ion-textarea.entry.js +15 -6
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-1d65c601.entry.js +4 -0
- package/dist/ionic/p-33017191.entry.js +4 -0
- package/hydrate/index.js +31 -13
- package/hydrate/index.mjs +31 -13
- package/package.json +1 -1
- package/dist/ionic/p-08493d32.entry.js +0 -4
- package/dist/ionic/p-a30b23cf.entry.js +0 -4
package/components/ion-input.js
CHANGED
|
@@ -248,7 +248,16 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
248
248
|
* Checks if the input is in an invalid state based on validation classes
|
|
249
249
|
*/
|
|
250
250
|
checkValidationState() {
|
|
251
|
-
|
|
251
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
252
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
253
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
254
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
255
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
256
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
257
|
+
// Return true if we have both touched and invalid states from either framework
|
|
258
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
259
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
260
|
+
return isTouched && isInvalid;
|
|
252
261
|
}
|
|
253
262
|
connectedCallback() {
|
|
254
263
|
const { el } = this;
|
|
@@ -413,10 +422,10 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
413
422
|
* Renders the helper text or error text values
|
|
414
423
|
*/
|
|
415
424
|
renderHintText() {
|
|
416
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
425
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
417
426
|
return [
|
|
418
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
419
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
427
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
428
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
420
429
|
];
|
|
421
430
|
}
|
|
422
431
|
getHintTextID() {
|
|
@@ -534,7 +543,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
534
543
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
535
544
|
*/
|
|
536
545
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
537
|
-
return (h(Host, { key: '
|
|
546
|
+
return (h(Host, { key: '1a141906096fc637d7de923edf6a9ea3a0168f5f', class: createColorClasses(this.color, {
|
|
538
547
|
[mode]: true,
|
|
539
548
|
'has-value': hasValue,
|
|
540
549
|
'has-focus': hasFocus,
|
|
@@ -545,14 +554,14 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
545
554
|
'in-item': inItem,
|
|
546
555
|
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
|
547
556
|
'input-disabled': disabled,
|
|
548
|
-
}) }, h("label", { key: '
|
|
557
|
+
}) }, h("label", { key: '8371432bc0fd37099d3efc50705530965f27b9e1', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '3d113da062bddf47b1bc67e67162c11fe4ee7f10', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '3fe52ada4b91ebd21b21b1445b9d4009d47f8386', name: "start" }), h("input", Object.assign({ key: 'beda905e9d44797690149407ba814381ffd51d1d', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: 'bc8579a0acb727b348bcf277f296b2dac9cb583d', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
549
558
|
/**
|
|
550
559
|
* This prevents mobile browsers from
|
|
551
560
|
* blurring the input when the clear
|
|
552
561
|
* button is activated.
|
|
553
562
|
*/
|
|
554
563
|
ev.preventDefault();
|
|
555
|
-
}, onClick: this.clearTextInput }, h("ion-icon", { key: '
|
|
564
|
+
}, onClick: this.clearTextInput }, h("ion-icon", { key: '41a64ec6fce010eb225637998d93abd859a62be7', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '9a7e6eba584748fc037aa1694d7e6e399de8b20b', name: "end" })), shouldRenderHighlight && h("div", { key: 'b828e6dc43b50f46727dda196de7ad2fecc3ef30', class: "input-highlight" })), this.renderBottomContent()));
|
|
556
565
|
}
|
|
557
566
|
get el() { return this; }
|
|
558
567
|
static get watchers() { return {
|
|
@@ -207,7 +207,16 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
207
207
|
* Checks if the textarea is in an invalid state based on validation classes
|
|
208
208
|
*/
|
|
209
209
|
checkValidationState() {
|
|
210
|
-
|
|
210
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
211
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
212
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
213
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
214
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
215
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
216
|
+
// Return true if we have both touched and invalid states from either framework
|
|
217
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
218
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
219
|
+
return isTouched && isInvalid;
|
|
211
220
|
}
|
|
212
221
|
connectedCallback() {
|
|
213
222
|
const { el } = this;
|
|
@@ -426,10 +435,10 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
426
435
|
* Renders the helper text or error text values
|
|
427
436
|
*/
|
|
428
437
|
renderHintText() {
|
|
429
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
438
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
430
439
|
return [
|
|
431
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
432
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
440
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
441
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
433
442
|
];
|
|
434
443
|
}
|
|
435
444
|
getHintTextID() {
|
|
@@ -493,7 +502,7 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
493
502
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
494
503
|
*/
|
|
495
504
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
496
|
-
return (h(Host, { key: '
|
|
505
|
+
return (h(Host, { key: '803c7648de15b8569c3df01692548018cc660510', class: createColorClasses(this.color, {
|
|
497
506
|
[mode]: true,
|
|
498
507
|
'has-value': hasValue,
|
|
499
508
|
'has-focus': hasFocus,
|
|
@@ -502,7 +511,7 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
502
511
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
503
512
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
504
513
|
'textarea-disabled': disabled,
|
|
505
|
-
}) }, h("label", { key: '
|
|
514
|
+
}) }, h("label", { key: '0e3a4e5fc809437abc6780eb7f99a0c770bb9f94', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'ff8d71e2d53daf4999338232d3b0a597627a3276', class: "textarea-wrapper-inner" }, h("div", { key: '313f5a8dc8b62e8ae6a0638a7e201b2594c180eb', class: "start-slot-wrapper" }, h("slot", { key: '32db088d41398be935f7060138e4d80a832fea85', name: "start" })), h("div", { key: '24b63ff40ffcae8816f24d9c8a6ec2e7848e0e0b', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '2a4f918351f87d444d8922254eefa0941a6ca238', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), h("div", { key: '2c32636d2d13560de0a54507e1668eb9f4bcc2cf', class: "end-slot-wrapper" }, h("slot", { key: 'ccc3549246fd9d2e309958767a7a24e1be8545fd', name: "end" }))), shouldRenderHighlight && h("div", { key: 'f4719399ec530ce295b19817688b8d39d84b6b09', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
506
515
|
}
|
|
507
516
|
get el() { return this; }
|
|
508
517
|
static get watchers() { return {
|
|
@@ -249,7 +249,16 @@ const Input = class {
|
|
|
249
249
|
* Checks if the input is in an invalid state based on validation classes
|
|
250
250
|
*/
|
|
251
251
|
checkValidationState() {
|
|
252
|
-
|
|
252
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
253
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
254
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
255
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
256
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
257
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
258
|
+
// Return true if we have both touched and invalid states from either framework
|
|
259
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
260
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
261
|
+
return isTouched && isInvalid;
|
|
253
262
|
}
|
|
254
263
|
connectedCallback() {
|
|
255
264
|
const { el } = this;
|
|
@@ -414,10 +423,10 @@ const Input = class {
|
|
|
414
423
|
* Renders the helper text or error text values
|
|
415
424
|
*/
|
|
416
425
|
renderHintText() {
|
|
417
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
426
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
418
427
|
return [
|
|
419
|
-
index.h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
420
|
-
index.h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
428
|
+
helperText && (index.h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
429
|
+
errorText && (index.h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
421
430
|
];
|
|
422
431
|
}
|
|
423
432
|
getHintTextID() {
|
|
@@ -535,7 +544,7 @@ const Input = class {
|
|
|
535
544
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
536
545
|
*/
|
|
537
546
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
538
|
-
return (index.h(index.Host, { key: '
|
|
547
|
+
return (index.h(index.Host, { key: '1a141906096fc637d7de923edf6a9ea3a0168f5f', class: theme.createColorClasses(this.color, {
|
|
539
548
|
[mode]: true,
|
|
540
549
|
'has-value': hasValue,
|
|
541
550
|
'has-focus': hasFocus,
|
|
@@ -546,14 +555,14 @@ const Input = class {
|
|
|
546
555
|
'in-item': inItem,
|
|
547
556
|
'in-item-color': theme.hostContext('ion-item.ion-color', this.el),
|
|
548
557
|
'input-disabled': disabled,
|
|
549
|
-
}) }, index.h("label", { key: '
|
|
558
|
+
}) }, index.h("label", { key: '8371432bc0fd37099d3efc50705530965f27b9e1', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: '3d113da062bddf47b1bc67e67162c11fe4ee7f10', class: "native-wrapper", onClick: this.onLabelClick }, index.h("slot", { key: '3fe52ada4b91ebd21b21b1445b9d4009d47f8386', name: "start" }), index.h("input", Object.assign({ key: 'beda905e9d44797690149407ba814381ffd51d1d', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (index.h("button", { key: 'bc8579a0acb727b348bcf277f296b2dac9cb583d', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
550
559
|
/**
|
|
551
560
|
* This prevents mobile browsers from
|
|
552
561
|
* blurring the input when the clear
|
|
553
562
|
* button is activated.
|
|
554
563
|
*/
|
|
555
564
|
ev.preventDefault();
|
|
556
|
-
}, onClick: this.clearTextInput }, index.h("ion-icon", { key: '
|
|
565
|
+
}, onClick: this.clearTextInput }, index.h("ion-icon", { key: '41a64ec6fce010eb225637998d93abd859a62be7', "aria-hidden": "true", icon: clearIconData }))), index.h("slot", { key: '9a7e6eba584748fc037aa1694d7e6e399de8b20b', name: "end" })), shouldRenderHighlight && index.h("div", { key: 'b828e6dc43b50f46727dda196de7ad2fecc3ef30', class: "input-highlight" })), this.renderBottomContent()));
|
|
557
566
|
}
|
|
558
567
|
get el() { return index.getElement(this); }
|
|
559
568
|
static get watchers() { return {
|
|
@@ -209,7 +209,16 @@ const Textarea = class {
|
|
|
209
209
|
* Checks if the textarea is in an invalid state based on validation classes
|
|
210
210
|
*/
|
|
211
211
|
checkValidationState() {
|
|
212
|
-
|
|
212
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
213
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
214
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
215
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
216
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
217
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
218
|
+
// Return true if we have both touched and invalid states from either framework
|
|
219
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
220
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
221
|
+
return isTouched && isInvalid;
|
|
213
222
|
}
|
|
214
223
|
connectedCallback() {
|
|
215
224
|
const { el } = this;
|
|
@@ -428,10 +437,10 @@ const Textarea = class {
|
|
|
428
437
|
* Renders the helper text or error text values
|
|
429
438
|
*/
|
|
430
439
|
renderHintText() {
|
|
431
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
440
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
432
441
|
return [
|
|
433
|
-
index.h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
434
|
-
index.h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
442
|
+
helperText && (index.h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
443
|
+
errorText && (index.h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
435
444
|
];
|
|
436
445
|
}
|
|
437
446
|
getHintTextID() {
|
|
@@ -495,7 +504,7 @@ const Textarea = class {
|
|
|
495
504
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
496
505
|
*/
|
|
497
506
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
498
|
-
return (index.h(index.Host, { key: '
|
|
507
|
+
return (index.h(index.Host, { key: '803c7648de15b8569c3df01692548018cc660510', class: theme.createColorClasses(this.color, {
|
|
499
508
|
[mode]: true,
|
|
500
509
|
'has-value': hasValue,
|
|
501
510
|
'has-focus': hasFocus,
|
|
@@ -504,7 +513,7 @@ const Textarea = class {
|
|
|
504
513
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
505
514
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
506
515
|
'textarea-disabled': disabled,
|
|
507
|
-
}) }, index.h("label", { key: '
|
|
516
|
+
}) }, index.h("label", { key: '0e3a4e5fc809437abc6780eb7f99a0c770bb9f94', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: 'ff8d71e2d53daf4999338232d3b0a597627a3276', class: "textarea-wrapper-inner" }, index.h("div", { key: '313f5a8dc8b62e8ae6a0638a7e201b2594c180eb', class: "start-slot-wrapper" }, index.h("slot", { key: '32db088d41398be935f7060138e4d80a832fea85', name: "start" })), index.h("div", { key: '24b63ff40ffcae8816f24d9c8a6ec2e7848e0e0b', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, index.h("textarea", Object.assign({ key: '2a4f918351f87d444d8922254eefa0941a6ca238', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), index.h("div", { key: '2c32636d2d13560de0a54507e1668eb9f4bcc2cf', class: "end-slot-wrapper" }, index.h("slot", { key: 'ccc3549246fd9d2e309958767a7a24e1be8545fd', name: "end" }))), shouldRenderHighlight && index.h("div", { key: 'f4719399ec530ce295b19817688b8d39d84b6b09', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
508
517
|
}
|
|
509
518
|
get el() { return index.getElement(this); }
|
|
510
519
|
static get watchers() { return {
|
|
@@ -244,7 +244,16 @@ export class Input {
|
|
|
244
244
|
* Checks if the input is in an invalid state based on validation classes
|
|
245
245
|
*/
|
|
246
246
|
checkValidationState() {
|
|
247
|
-
|
|
247
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
248
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
249
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
250
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
251
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
252
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
253
|
+
// Return true if we have both touched and invalid states from either framework
|
|
254
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
255
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
256
|
+
return isTouched && isInvalid;
|
|
248
257
|
}
|
|
249
258
|
connectedCallback() {
|
|
250
259
|
const { el } = this;
|
|
@@ -409,10 +418,10 @@ export class Input {
|
|
|
409
418
|
* Renders the helper text or error text values
|
|
410
419
|
*/
|
|
411
420
|
renderHintText() {
|
|
412
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
421
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
413
422
|
return [
|
|
414
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
415
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
423
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
424
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
416
425
|
];
|
|
417
426
|
}
|
|
418
427
|
getHintTextID() {
|
|
@@ -530,7 +539,7 @@ export class Input {
|
|
|
530
539
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
531
540
|
*/
|
|
532
541
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
533
|
-
return (h(Host, { key: '
|
|
542
|
+
return (h(Host, { key: '1a141906096fc637d7de923edf6a9ea3a0168f5f', class: createColorClasses(this.color, {
|
|
534
543
|
[mode]: true,
|
|
535
544
|
'has-value': hasValue,
|
|
536
545
|
'has-focus': hasFocus,
|
|
@@ -541,14 +550,14 @@ export class Input {
|
|
|
541
550
|
'in-item': inItem,
|
|
542
551
|
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
|
543
552
|
'input-disabled': disabled,
|
|
544
|
-
}) }, h("label", { key: '
|
|
553
|
+
}) }, h("label", { key: '8371432bc0fd37099d3efc50705530965f27b9e1', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '3d113da062bddf47b1bc67e67162c11fe4ee7f10', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '3fe52ada4b91ebd21b21b1445b9d4009d47f8386', name: "start" }), h("input", Object.assign({ key: 'beda905e9d44797690149407ba814381ffd51d1d', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: 'bc8579a0acb727b348bcf277f296b2dac9cb583d', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
545
554
|
/**
|
|
546
555
|
* This prevents mobile browsers from
|
|
547
556
|
* blurring the input when the clear
|
|
548
557
|
* button is activated.
|
|
549
558
|
*/
|
|
550
559
|
ev.preventDefault();
|
|
551
|
-
}, onClick: this.clearTextInput }, h("ion-icon", { key: '
|
|
560
|
+
}, onClick: this.clearTextInput }, h("ion-icon", { key: '41a64ec6fce010eb225637998d93abd859a62be7', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '9a7e6eba584748fc037aa1694d7e6e399de8b20b', name: "end" })), shouldRenderHighlight && h("div", { key: 'b828e6dc43b50f46727dda196de7ad2fecc3ef30', class: "input-highlight" })), this.renderBottomContent()));
|
|
552
561
|
}
|
|
553
562
|
static get is() { return "ion-input"; }
|
|
554
563
|
static get encapsulation() { return "scoped"; }
|
|
@@ -204,7 +204,16 @@ export class Textarea {
|
|
|
204
204
|
* Checks if the textarea is in an invalid state based on validation classes
|
|
205
205
|
*/
|
|
206
206
|
checkValidationState() {
|
|
207
|
-
|
|
207
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
208
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
209
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
210
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
211
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
212
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
213
|
+
// Return true if we have both touched and invalid states from either framework
|
|
214
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
215
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
216
|
+
return isTouched && isInvalid;
|
|
208
217
|
}
|
|
209
218
|
connectedCallback() {
|
|
210
219
|
const { el } = this;
|
|
@@ -423,10 +432,10 @@ export class Textarea {
|
|
|
423
432
|
* Renders the helper text or error text values
|
|
424
433
|
*/
|
|
425
434
|
renderHintText() {
|
|
426
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
435
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
427
436
|
return [
|
|
428
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
429
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
437
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
438
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
430
439
|
];
|
|
431
440
|
}
|
|
432
441
|
getHintTextID() {
|
|
@@ -490,7 +499,7 @@ export class Textarea {
|
|
|
490
499
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
491
500
|
*/
|
|
492
501
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
493
|
-
return (h(Host, { key: '
|
|
502
|
+
return (h(Host, { key: '803c7648de15b8569c3df01692548018cc660510', class: createColorClasses(this.color, {
|
|
494
503
|
[mode]: true,
|
|
495
504
|
'has-value': hasValue,
|
|
496
505
|
'has-focus': hasFocus,
|
|
@@ -499,7 +508,7 @@ export class Textarea {
|
|
|
499
508
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
500
509
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
501
510
|
'textarea-disabled': disabled,
|
|
502
|
-
}) }, h("label", { key: '
|
|
511
|
+
}) }, h("label", { key: '0e3a4e5fc809437abc6780eb7f99a0c770bb9f94', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'ff8d71e2d53daf4999338232d3b0a597627a3276', class: "textarea-wrapper-inner" }, h("div", { key: '313f5a8dc8b62e8ae6a0638a7e201b2594c180eb', class: "start-slot-wrapper" }, h("slot", { key: '32db088d41398be935f7060138e4d80a832fea85', name: "start" })), h("div", { key: '24b63ff40ffcae8816f24d9c8a6ec2e7848e0e0b', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '2a4f918351f87d444d8922254eefa0941a6ca238', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), h("div", { key: '2c32636d2d13560de0a54507e1668eb9f4bcc2cf', class: "end-slot-wrapper" }, h("slot", { key: 'ccc3549246fd9d2e309958767a7a24e1be8545fd', name: "end" }))), shouldRenderHighlight && h("div", { key: 'f4719399ec530ce295b19817688b8d39d84b6b09', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
503
512
|
}
|
|
504
513
|
static get is() { return "ion-textarea"; }
|
|
505
514
|
static get encapsulation() { return "scoped"; }
|
package/dist/docs.json
CHANGED
|
@@ -247,7 +247,16 @@ const Input = class {
|
|
|
247
247
|
* Checks if the input is in an invalid state based on validation classes
|
|
248
248
|
*/
|
|
249
249
|
checkValidationState() {
|
|
250
|
-
|
|
250
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
251
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
252
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
253
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
254
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
255
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
256
|
+
// Return true if we have both touched and invalid states from either framework
|
|
257
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
258
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
259
|
+
return isTouched && isInvalid;
|
|
251
260
|
}
|
|
252
261
|
connectedCallback() {
|
|
253
262
|
const { el } = this;
|
|
@@ -412,10 +421,10 @@ const Input = class {
|
|
|
412
421
|
* Renders the helper text or error text values
|
|
413
422
|
*/
|
|
414
423
|
renderHintText() {
|
|
415
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
424
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
416
425
|
return [
|
|
417
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
418
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
426
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
427
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
419
428
|
];
|
|
420
429
|
}
|
|
421
430
|
getHintTextID() {
|
|
@@ -533,7 +542,7 @@ const Input = class {
|
|
|
533
542
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
534
543
|
*/
|
|
535
544
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
536
|
-
return (h(Host, { key: '
|
|
545
|
+
return (h(Host, { key: '1a141906096fc637d7de923edf6a9ea3a0168f5f', class: createColorClasses(this.color, {
|
|
537
546
|
[mode]: true,
|
|
538
547
|
'has-value': hasValue,
|
|
539
548
|
'has-focus': hasFocus,
|
|
@@ -544,14 +553,14 @@ const Input = class {
|
|
|
544
553
|
'in-item': inItem,
|
|
545
554
|
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
|
546
555
|
'input-disabled': disabled,
|
|
547
|
-
}) }, h("label", { key: '
|
|
556
|
+
}) }, h("label", { key: '8371432bc0fd37099d3efc50705530965f27b9e1', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '3d113da062bddf47b1bc67e67162c11fe4ee7f10', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '3fe52ada4b91ebd21b21b1445b9d4009d47f8386', name: "start" }), h("input", Object.assign({ key: 'beda905e9d44797690149407ba814381ffd51d1d', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: 'bc8579a0acb727b348bcf277f296b2dac9cb583d', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
548
557
|
/**
|
|
549
558
|
* This prevents mobile browsers from
|
|
550
559
|
* blurring the input when the clear
|
|
551
560
|
* button is activated.
|
|
552
561
|
*/
|
|
553
562
|
ev.preventDefault();
|
|
554
|
-
}, onClick: this.clearTextInput }, h("ion-icon", { key: '
|
|
563
|
+
}, onClick: this.clearTextInput }, h("ion-icon", { key: '41a64ec6fce010eb225637998d93abd859a62be7', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '9a7e6eba584748fc037aa1694d7e6e399de8b20b', name: "end" })), shouldRenderHighlight && h("div", { key: 'b828e6dc43b50f46727dda196de7ad2fecc3ef30', class: "input-highlight" })), this.renderBottomContent()));
|
|
555
564
|
}
|
|
556
565
|
get el() { return getElement(this); }
|
|
557
566
|
static get watchers() { return {
|
|
@@ -207,7 +207,16 @@ const Textarea = class {
|
|
|
207
207
|
* Checks if the textarea is in an invalid state based on validation classes
|
|
208
208
|
*/
|
|
209
209
|
checkValidationState() {
|
|
210
|
-
|
|
210
|
+
// Check for both Ionic and Angular validation classes on the element itself
|
|
211
|
+
// Angular applies ng-touched/ng-invalid directly to the host element with ngModel
|
|
212
|
+
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
213
|
+
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
214
|
+
const hasNgTouched = this.el.classList.contains('ng-touched');
|
|
215
|
+
const hasNgInvalid = this.el.classList.contains('ng-invalid');
|
|
216
|
+
// Return true if we have both touched and invalid states from either framework
|
|
217
|
+
const isTouched = hasIonTouched || hasNgTouched;
|
|
218
|
+
const isInvalid = hasIonInvalid || hasNgInvalid;
|
|
219
|
+
return isTouched && isInvalid;
|
|
211
220
|
}
|
|
212
221
|
connectedCallback() {
|
|
213
222
|
const { el } = this;
|
|
@@ -426,10 +435,10 @@ const Textarea = class {
|
|
|
426
435
|
* Renders the helper text or error text values
|
|
427
436
|
*/
|
|
428
437
|
renderHintText() {
|
|
429
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
438
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
430
439
|
return [
|
|
431
|
-
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
432
|
-
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
440
|
+
helperText && (h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, helperText)),
|
|
441
|
+
errorText && (h("div", { id: errorTextId, class: "error-text", "aria-live": "assertive", "aria-atomic": "true", role: "alert", style: { display: isInvalid ? 'block' : 'none' } }, errorText)),
|
|
433
442
|
];
|
|
434
443
|
}
|
|
435
444
|
getHintTextID() {
|
|
@@ -493,7 +502,7 @@ const Textarea = class {
|
|
|
493
502
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
494
503
|
*/
|
|
495
504
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
496
|
-
return (h(Host, { key: '
|
|
505
|
+
return (h(Host, { key: '803c7648de15b8569c3df01692548018cc660510', class: createColorClasses(this.color, {
|
|
497
506
|
[mode]: true,
|
|
498
507
|
'has-value': hasValue,
|
|
499
508
|
'has-focus': hasFocus,
|
|
@@ -502,7 +511,7 @@ const Textarea = class {
|
|
|
502
511
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
503
512
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
504
513
|
'textarea-disabled': disabled,
|
|
505
|
-
}) }, h("label", { key: '
|
|
514
|
+
}) }, h("label", { key: '0e3a4e5fc809437abc6780eb7f99a0c770bb9f94', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'ff8d71e2d53daf4999338232d3b0a597627a3276', class: "textarea-wrapper-inner" }, h("div", { key: '313f5a8dc8b62e8ae6a0638a7e201b2594c180eb', class: "start-slot-wrapper" }, h("slot", { key: '32db088d41398be935f7060138e4d80a832fea85', name: "start" })), h("div", { key: '24b63ff40ffcae8816f24d9c8a6ec2e7848e0e0b', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '2a4f918351f87d444d8922254eefa0941a6ca238', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), h("div", { key: '2c32636d2d13560de0a54507e1668eb9f4bcc2cf', class: "end-slot-wrapper" }, h("slot", { key: 'ccc3549246fd9d2e309958767a7a24e1be8545fd', name: "end" }))), shouldRenderHighlight && h("div", { key: 'f4719399ec530ce295b19817688b8d39d84b6b09', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
506
515
|
}
|
|
507
516
|
get el() { return getElement(this); }
|
|
508
517
|
static get watchers() { return {
|