voyager-ionic-core 8.7.6 → 8.7.11
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/button.js +3 -7
- package/components/checkbox.js +64 -13
- package/components/header.js +42 -4
- package/components/index2.js +74 -3
- package/components/ion-accordion.js +93 -14
- package/components/ion-datetime.js +35 -2
- package/components/ion-input.js +6 -13
- package/components/ion-select.js +59 -10
- package/components/ion-textarea.js +5 -12
- package/components/ion-toggle.js +63 -16
- package/components/radio-group.js +60 -7
- package/components/validity.js +17 -0
- package/dist/cjs/{index-CD5Rjp23.js → index-094mMFB-.js} +76 -5
- package/dist/cjs/index.cjs.js +3 -3
- package/dist/cjs/ion-accordion_2.cjs.entry.js +91 -13
- package/dist/cjs/ion-app_8.cjs.entry.js +43 -5
- package/dist/cjs/ion-button_2.cjs.entry.js +3 -7
- package/dist/cjs/ion-checkbox.cjs.entry.js +61 -12
- package/dist/cjs/ion-datetime_3.cjs.entry.js +35 -2
- package/dist/cjs/ion-input.cjs.entry.js +6 -13
- package/dist/cjs/ion-modal.cjs.entry.js +1 -1
- package/dist/cjs/ion-nav_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-popover.cjs.entry.js +1 -1
- package/dist/cjs/ion-radio_2.cjs.entry.js +57 -6
- package/dist/cjs/ion-select_3.cjs.entry.js +56 -9
- package/dist/cjs/ion-textarea.cjs.entry.js +5 -12
- package/dist/cjs/ion-toggle.cjs.entry.js +59 -14
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/{ios.transition-j9CclgEW.js → ios.transition-BOt_uW73.js} +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{md.transition-CwFyRSfv.js → md.transition-Dt968VXB.js} +1 -1
- package/dist/cjs/validity-BpS37YFM.js +19 -0
- package/dist/collection/components/accordion/accordion.js +93 -14
- package/dist/collection/components/button/button.js +3 -7
- package/dist/collection/components/checkbox/checkbox.js +68 -13
- package/dist/collection/components/datetime/datetime.js +35 -2
- package/dist/collection/components/header/header.ios.css +27 -1
- package/dist/collection/components/header/header.js +5 -4
- package/dist/collection/components/header/header.utils.js +37 -0
- package/dist/collection/components/input/input.js +6 -14
- package/dist/collection/components/radio-group/radio-group.js +64 -7
- package/dist/collection/components/select/select.js +60 -12
- package/dist/collection/components/textarea/textarea.js +5 -13
- package/dist/collection/components/toggle/toggle.js +63 -16
- package/dist/collection/utils/forms/index.js +1 -0
- package/dist/collection/utils/forms/validity.js +15 -0
- package/dist/collection/utils/test/playwright/page/utils/set-content.js +7 -0
- package/dist/collection/utils/test/playwright/page/utils/spy-on-event.js +32 -0
- package/dist/collection/utils/transition/index.js +74 -3
- package/dist/docs.json +1 -1
- package/dist/esm/{index-D6G2seR8.js → index-r2D9DEro.js} +76 -5
- package/dist/esm/index.js +3 -3
- package/dist/esm/ion-accordion_2.entry.js +91 -13
- package/dist/esm/ion-app_8.entry.js +43 -5
- package/dist/esm/ion-button_2.entry.js +3 -7
- package/dist/esm/ion-checkbox.entry.js +61 -12
- package/dist/esm/ion-datetime_3.entry.js +35 -2
- package/dist/esm/ion-input.entry.js +6 -13
- package/dist/esm/ion-modal.entry.js +1 -1
- package/dist/esm/ion-nav_2.entry.js +1 -1
- package/dist/esm/ion-popover.entry.js +1 -1
- package/dist/esm/ion-radio_2.entry.js +57 -6
- package/dist/esm/ion-select_3.entry.js +56 -9
- package/dist/esm/ion-textarea.entry.js +5 -12
- package/dist/esm/ion-toggle.entry.js +59 -14
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/{ios.transition-Bpq9ixwv.js → ios.transition-BDzw0_Hm.js} +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{md.transition-zOA0oanq.js → md.transition-BzDYi3qq.js} +1 -1
- package/dist/esm/validity-DJztqcrH.js +17 -0
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-40c261a3.entry.js +4 -0
- package/dist/ionic/p-43ed1ef5.entry.js +4 -0
- package/dist/ionic/p-4e41ea20.entry.js +4 -0
- package/dist/ionic/{p-323421af.entry.js → p-5a39a99a.entry.js} +1 -1
- package/dist/ionic/p-5fb517e4.entry.js +4 -0
- package/dist/ionic/p-7380261c.entry.js +4 -0
- package/dist/ionic/{p-9a36e2e7.entry.js → p-95bddd49.entry.js} +1 -1
- package/dist/ionic/{p-DPhQmGJN.js → p-C7hRNDhM.js} +1 -1
- package/dist/ionic/p-DJztqcrH.js +4 -0
- package/dist/ionic/p-DUt5fQmA.js +4 -0
- package/dist/ionic/{p-9R1XyICs.js → p-DZRJwG4S.js} +1 -1
- package/dist/ionic/p-c19f63d0.entry.js +4 -0
- package/dist/ionic/p-cb93126d.entry.js +4 -0
- package/dist/ionic/p-d0a2a1ab.entry.js +4 -0
- package/dist/ionic/p-d1f54e28.entry.js +4 -0
- package/dist/ionic/p-d3014190.entry.js +4 -0
- package/dist/ionic/{p-de7b5fa3.entry.js → p-e16b69e1.entry.js} +1 -1
- package/dist/ionic/svg/checkbox-outline.svg +1 -0
- package/dist/ionic/svg/checkbox-sharp.svg +1 -0
- package/dist/ionic/svg/checkbox.svg +1 -0
- package/dist/ionic/svg/checkmark-circle-outline.svg +1 -0
- package/dist/ionic/svg/checkmark-circle-sharp.svg +1 -0
- package/dist/ionic/svg/checkmark-circle.svg +1 -0
- package/dist/ionic/svg/checkmark-done-circle-outline.svg +1 -0
- package/dist/ionic/svg/checkmark-done-circle-sharp.svg +1 -0
- package/dist/ionic/svg/checkmark-done-circle.svg +1 -0
- package/dist/ionic/svg/checkmark-done-outline.svg +1 -0
- package/dist/ionic/svg/checkmark-done-sharp.svg +1 -0
- package/dist/ionic/svg/checkmark-done.svg +1 -0
- package/dist/ionic/svg/checkmark-outline.svg +1 -0
- package/dist/ionic/svg/checkmark-sharp.svg +1 -0
- package/dist/ionic/svg/checkmark.svg +1 -0
- package/dist/ionic/svg/chevron-back-circle-outline.svg +1 -0
- package/dist/ionic/svg/chevron-back-circle-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-back-circle.svg +1 -0
- package/dist/ionic/svg/chevron-back-outline.svg +1 -0
- package/dist/ionic/svg/chevron-back-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-back.svg +1 -0
- package/dist/ionic/svg/chevron-collapse-outline.svg +1 -0
- package/dist/ionic/svg/chevron-collapse-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-collapse.svg +1 -0
- package/dist/ionic/svg/chevron-down-circle-outline.svg +1 -0
- package/dist/ionic/svg/chevron-down-circle-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-down-circle.svg +1 -0
- package/dist/ionic/svg/chevron-down-outline.svg +1 -0
- package/dist/ionic/svg/chevron-down-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-down.svg +1 -0
- package/dist/ionic/svg/chevron-expand-outline.svg +1 -0
- package/dist/ionic/svg/chevron-expand-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-expand.svg +1 -0
- package/dist/ionic/svg/chevron-forward-circle-outline.svg +1 -0
- package/dist/ionic/svg/chevron-forward-circle-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-forward-circle.svg +1 -0
- package/dist/ionic/svg/chevron-forward-outline.svg +1 -0
- package/dist/ionic/svg/chevron-forward-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-forward.svg +1 -0
- package/dist/ionic/svg/chevron-up-circle-outline.svg +1 -0
- package/dist/ionic/svg/chevron-up-circle-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-up-circle.svg +1 -0
- package/dist/ionic/svg/chevron-up-outline.svg +1 -0
- package/dist/ionic/svg/chevron-up-sharp.svg +1 -0
- package/dist/ionic/svg/chevron-up.svg +1 -0
- package/dist/ionic/svg/clipboard-outline.svg +1 -0
- package/dist/ionic/svg/clipboard-sharp.svg +1 -0
- package/dist/ionic/svg/clipboard.svg +1 -0
- package/dist/ionic/svg/close-circle-outline.svg +1 -0
- package/dist/ionic/svg/close-circle-sharp.svg +1 -0
- package/dist/ionic/svg/close-circle.svg +1 -0
- package/dist/ionic/svg/close-outline.svg +1 -0
- package/dist/ionic/svg/close-sharp.svg +1 -0
- package/dist/ionic/svg/close.svg +1 -0
- package/dist/ionic/svg/cloud-circle-outline.svg +1 -0
- package/dist/ionic/svg/cloud-circle-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-circle.svg +1 -0
- package/dist/ionic/svg/cloud-done-outline.svg +1 -0
- package/dist/ionic/svg/cloud-done-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-done.svg +1 -0
- package/dist/ionic/svg/cloud-download-outline.svg +1 -0
- package/dist/ionic/svg/cloud-download-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-download.svg +1 -0
- package/dist/ionic/svg/cloud-offline-outline.svg +1 -0
- package/dist/ionic/svg/cloud-offline-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-offline.svg +1 -0
- package/dist/ionic/svg/cloud-outline.svg +1 -0
- package/dist/ionic/svg/cloud-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-upload-outline.svg +1 -0
- package/dist/ionic/svg/cloud-upload-sharp.svg +1 -0
- package/dist/ionic/svg/cloud-upload.svg +1 -0
- package/dist/ionic/svg/cloud.svg +1 -0
- package/dist/ionic/svg/cloudy-night-outline.svg +1 -0
- package/dist/ionic/svg/cloudy-night-sharp.svg +1 -0
- package/dist/ionic/svg/cloudy-night.svg +1 -0
- package/dist/ionic/svg/cloudy-outline.svg +1 -0
- package/dist/ionic/svg/cloudy-sharp.svg +1 -0
- package/dist/ionic/svg/cloudy.svg +1 -0
- package/dist/ionic/svg/code-download-outline.svg +1 -0
- package/dist/ionic/svg/code-download-sharp.svg +1 -0
- package/dist/ionic/svg/code-download.svg +1 -0
- package/dist/ionic/svg/code-outline.svg +1 -0
- package/dist/ionic/svg/code-sharp.svg +1 -0
- package/dist/ionic/svg/code-slash-outline.svg +1 -0
- package/dist/ionic/svg/code-slash-sharp.svg +1 -0
- package/dist/ionic/svg/code-slash.svg +1 -0
- package/dist/ionic/svg/code-working-outline.svg +1 -0
- package/dist/ionic/svg/code-working-sharp.svg +1 -0
- package/dist/ionic/svg/code-working.svg +1 -0
- package/dist/ionic/svg/code.svg +1 -0
- package/dist/ionic/svg/cog-outline.svg +1 -0
- package/dist/ionic/svg/cog-sharp.svg +1 -0
- package/dist/ionic/svg/cog.svg +1 -0
- package/dist/ionic/svg/color-fill-outline.svg +1 -0
- package/dist/ionic/svg/color-fill-sharp.svg +1 -0
- package/dist/ionic/svg/color-fill.svg +1 -0
- package/dist/ionic/svg/color-filter-outline.svg +1 -0
- package/dist/ionic/svg/color-filter-sharp.svg +1 -0
- package/dist/ionic/svg/color-filter.svg +1 -0
- package/dist/ionic/svg/color-palette-outline.svg +1 -0
- package/dist/ionic/svg/color-palette-sharp.svg +1 -0
- package/dist/ionic/svg/color-palette.svg +1 -0
- package/dist/ionic/svg/color-wand-outline.svg +1 -0
- package/dist/ionic/svg/color-wand-sharp.svg +1 -0
- package/dist/ionic/svg/color-wand.svg +1 -0
- package/dist/ionic/svg/compass-outline.svg +1 -0
- package/dist/ionic/svg/compass-sharp.svg +1 -0
- package/dist/ionic/svg/compass.svg +1 -0
- package/dist/ionic/svg/construct-outline.svg +1 -0
- package/dist/ionic/svg/construct-sharp.svg +1 -0
- package/dist/ionic/svg/construct.svg +1 -0
- package/dist/ionic/svg/contract-outline.svg +1 -0
- package/dist/ionic/svg/contract-sharp.svg +1 -0
- package/dist/ionic/svg/contract.svg +1 -0
- package/dist/ionic/svg/contrast-outline.svg +1 -0
- package/dist/ionic/svg/contrast-sharp.svg +1 -0
- package/dist/ionic/svg/contrast.svg +1 -0
- package/dist/ionic/svg/copy-outline.svg +1 -0
- package/dist/ionic/svg/copy-sharp.svg +1 -0
- package/dist/ionic/svg/copy.svg +1 -0
- package/dist/ionic/svg/create-outline.svg +1 -0
- package/dist/ionic/svg/create-sharp.svg +1 -0
- package/dist/ionic/svg/create.svg +1 -0
- package/dist/ionic/svg/crop-outline.svg +1 -0
- package/dist/ionic/svg/crop-sharp.svg +1 -0
- package/dist/ionic/svg/crop.svg +1 -0
- package/dist/ionic/svg/cube-outline.svg +1 -0
- package/dist/ionic/svg/cube-sharp.svg +1 -0
- package/dist/ionic/svg/cube.svg +1 -0
- package/dist/ionic/svg/cut-outline.svg +1 -0
- package/dist/ionic/svg/cut-sharp.svg +1 -0
- package/dist/ionic/svg/cut.svg +1 -0
- package/dist/ionic/svg/desktop-outline.svg +1 -0
- package/dist/ionic/svg/desktop-sharp.svg +1 -0
- package/dist/ionic/svg/desktop.svg +1 -0
- package/dist/ionic/svg/diamond-outline.svg +1 -0
- package/dist/ionic/svg/diamond-sharp.svg +1 -0
- package/dist/ionic/svg/diamond.svg +1 -0
- package/dist/ionic/svg/dice-outline.svg +1 -0
- package/dist/ionic/svg/dice-sharp.svg +1 -0
- package/dist/ionic/svg/dice.svg +1 -0
- package/dist/ionic/svg/disc-outline.svg +1 -0
- package/dist/ionic/svg/disc-sharp.svg +1 -0
- package/dist/ionic/svg/disc.svg +1 -0
- package/dist/ionic/svg/document-attach-outline.svg +1 -0
- package/dist/ionic/svg/document-attach-sharp.svg +1 -0
- package/dist/ionic/svg/document-attach.svg +1 -0
- package/dist/ionic/svg/document-lock-outline.svg +1 -0
- package/dist/ionic/svg/document-lock-sharp.svg +1 -0
- package/dist/ionic/svg/document-lock.svg +1 -0
- package/dist/ionic/svg/document-outline.svg +1 -0
- package/dist/types/components/accordion/accordion.d.ts +18 -1
- package/dist/types/components/checkbox/checkbox.d.ts +9 -2
- package/dist/types/components/datetime/datetime.d.ts +10 -0
- package/dist/types/components/header/header.utils.d.ts +10 -0
- package/dist/types/components/input/input.d.ts +0 -4
- package/dist/types/components/radio-group/radio-group.d.ts +9 -1
- package/dist/types/components/select/select.d.ts +7 -1
- package/dist/types/components/textarea/textarea.d.ts +0 -4
- package/dist/types/components/toggle/toggle.d.ts +7 -2
- package/dist/types/utils/forms/index.d.ts +1 -0
- package/dist/types/utils/forms/validity.d.ts +10 -0
- package/dist/types/utils/transition/index.d.ts +9 -0
- package/hydrate/index.js +687 -413
- package/hydrate/index.mjs +687 -413
- package/package.json +4 -4
- package/dist/ionic/p-1c8a476d.entry.js +0 -4
- package/dist/ionic/p-3355a2ff.entry.js +0 -4
- package/dist/ionic/p-4efea47a.entry.js +0 -4
- package/dist/ionic/p-62e50f80.entry.js +0 -4
- package/dist/ionic/p-785026d7.entry.js +0 -4
- package/dist/ionic/p-78c74a3e.entry.js +0 -4
- package/dist/ionic/p-7bcfc421.entry.js +0 -4
- package/dist/ionic/p-83fc84e7.entry.js +0 -4
- package/dist/ionic/p-913a7c1e.entry.js +0 -4
- package/dist/ionic/p-CMhMiYSX.js +0 -4
- package/dist/ionic/p-c17c0a01.entry.js +0 -4
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { r as registerInstance, c as createEvent, h, d as Host, g as getElement } from './index-C8IsBmNU.js';
|
|
5
5
|
import { i as inheritAriaAttributes, a as renderHiddenInput } from './helpers-DEn3pfjm.js';
|
|
6
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
6
7
|
import { c as createColorClasses, h as hostContext } from './theme-DiVJyqlX.js';
|
|
7
8
|
import { b as getIonMode } from './ionic-global-CDrldh-5.js';
|
|
8
9
|
|
|
@@ -59,6 +60,10 @@ const Checkbox = class {
|
|
|
59
60
|
* submitting if the value is invalid.
|
|
60
61
|
*/
|
|
61
62
|
this.required = false;
|
|
63
|
+
/**
|
|
64
|
+
* Track validation state for proper aria-live announcements.
|
|
65
|
+
*/
|
|
66
|
+
this.isInvalid = false;
|
|
62
67
|
/**
|
|
63
68
|
* Sets the checked property and emits
|
|
64
69
|
* the ionChange event. Use this to update the
|
|
@@ -74,7 +79,6 @@ const Checkbox = class {
|
|
|
74
79
|
};
|
|
75
80
|
this.toggleChecked = (ev) => {
|
|
76
81
|
ev.preventDefault();
|
|
77
|
-
this.setFocus();
|
|
78
82
|
this.setChecked(!this.checked);
|
|
79
83
|
this.indeterminate = false;
|
|
80
84
|
};
|
|
@@ -106,18 +110,63 @@ const Checkbox = class {
|
|
|
106
110
|
ev.stopPropagation();
|
|
107
111
|
};
|
|
108
112
|
}
|
|
113
|
+
connectedCallback() {
|
|
114
|
+
const { el } = this;
|
|
115
|
+
// Watch for class changes to update validation state.
|
|
116
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
117
|
+
this.validationObserver = new MutationObserver(() => {
|
|
118
|
+
const newIsInvalid = checkInvalidState(el);
|
|
119
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
120
|
+
this.isInvalid = newIsInvalid;
|
|
121
|
+
/**
|
|
122
|
+
* Screen readers tend to announce changes
|
|
123
|
+
* to `aria-describedby` when the attribute
|
|
124
|
+
* is changed during a blur event for a
|
|
125
|
+
* native form control.
|
|
126
|
+
* However, the announcement can be spotty
|
|
127
|
+
* when using a non-native form control
|
|
128
|
+
* and `forceUpdate()`.
|
|
129
|
+
* This is due to `forceUpdate()` internally
|
|
130
|
+
* rescheduling the DOM update to a lower
|
|
131
|
+
* priority queue regardless if it's called
|
|
132
|
+
* inside a Promise or not, thus causing
|
|
133
|
+
* the screen reader to potentially miss the
|
|
134
|
+
* change.
|
|
135
|
+
* By using a State variable inside a Promise,
|
|
136
|
+
* it guarantees a re-render immediately at
|
|
137
|
+
* a higher priority.
|
|
138
|
+
*/
|
|
139
|
+
Promise.resolve().then(() => {
|
|
140
|
+
this.hintTextId = this.getHintTextId();
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
this.validationObserver.observe(el, {
|
|
145
|
+
attributes: true,
|
|
146
|
+
attributeFilter: ['class'],
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// Always set initial state
|
|
150
|
+
this.isInvalid = checkInvalidState(el);
|
|
151
|
+
}
|
|
109
152
|
componentWillLoad() {
|
|
110
153
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
154
|
+
this.hintTextId = this.getHintTextId();
|
|
155
|
+
}
|
|
156
|
+
disconnectedCallback() {
|
|
157
|
+
// Clean up validation observer to prevent memory leaks.
|
|
158
|
+
if (this.validationObserver) {
|
|
159
|
+
this.validationObserver.disconnect();
|
|
160
|
+
this.validationObserver = undefined;
|
|
161
|
+
}
|
|
111
162
|
}
|
|
112
163
|
/** @internal */
|
|
113
164
|
async setFocus() {
|
|
114
|
-
|
|
115
|
-
this.focusEl.focus();
|
|
116
|
-
}
|
|
165
|
+
this.el.focus();
|
|
117
166
|
}
|
|
118
|
-
|
|
119
|
-
const {
|
|
120
|
-
if (
|
|
167
|
+
getHintTextId() {
|
|
168
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
169
|
+
if (isInvalid && errorText) {
|
|
121
170
|
return errorTextId;
|
|
122
171
|
}
|
|
123
172
|
if (helperText) {
|
|
@@ -130,7 +179,7 @@ const Checkbox = class {
|
|
|
130
179
|
* This element should only be rendered if hint text is set.
|
|
131
180
|
*/
|
|
132
181
|
renderHintText() {
|
|
133
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
182
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
134
183
|
/**
|
|
135
184
|
* undefined and empty string values should
|
|
136
185
|
* be treated as not having helper/error text.
|
|
@@ -139,7 +188,7 @@ const Checkbox = class {
|
|
|
139
188
|
if (!hasHintText) {
|
|
140
189
|
return;
|
|
141
190
|
}
|
|
142
|
-
return (h("div", { class: "checkbox-bottom" }, h("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), h("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
|
|
191
|
+
return (h("div", { class: "checkbox-bottom" }, h("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null), h("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text", role: "alert" }, isInvalid ? errorText : null)));
|
|
143
192
|
}
|
|
144
193
|
render() {
|
|
145
194
|
const { color, checked, disabled, el, getSVGPath, indeterminate, inheritedAttributes, inputId, justify, labelPlacement, name, value, alignment, required, } = this;
|
|
@@ -149,7 +198,7 @@ const Checkbox = class {
|
|
|
149
198
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
150
199
|
// The host element must have a checkbox role to ensure proper VoiceOver
|
|
151
200
|
// support in Safari for accessibility.
|
|
152
|
-
return (h(Host, { key: '
|
|
201
|
+
return (h(Host, { key: 'ae0fbd4b21accbac132e6b85c513512ad9179394', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses(color, {
|
|
153
202
|
[mode]: true,
|
|
154
203
|
'in-item': hostContext('ion-item', el),
|
|
155
204
|
'checkbox-checked': checked,
|
|
@@ -159,10 +208,10 @@ const Checkbox = class {
|
|
|
159
208
|
[`checkbox-justify-${justify}`]: justify !== undefined,
|
|
160
209
|
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
|
|
161
210
|
[`checkbox-label-placement-${labelPlacement}`]: true,
|
|
162
|
-
})
|
|
211
|
+
}) }, h("label", { key: '7a3d7f3c27dde514f2dbf2e34f4629fad33ec3bf', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: '4130d77ddf034271fecccda14e101a5a809921b6', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), h("div", { key: '5daa74f4e62b0947e37764762524001ee42609d9', class: {
|
|
163
212
|
'label-text-wrapper': true,
|
|
164
213
|
'label-text-wrapper-hidden': !hasLabelContent,
|
|
165
|
-
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '
|
|
214
|
+
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '23ff66138f8c3a2f56f39113fc842d54b2f7952a' }), this.renderHintText()), h("div", { key: 'ab914d9623c19fc46821d5e62db92f1192ebbe7e', class: "native-wrapper" }, h("svg", { key: '66e3f4f5dcaa9756fb0e9452299954f9ed3dcb7b', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
|
|
166
215
|
}
|
|
167
216
|
getSVGPath(mode, indeterminate) {
|
|
168
217
|
let path = indeterminate ? (h("path", { d: "M6 12L18 12", part: "mark" })) : (h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
|
|
@@ -784,6 +784,28 @@ const Datetime = class {
|
|
|
784
784
|
destroyKeyboardMO();
|
|
785
785
|
}
|
|
786
786
|
};
|
|
787
|
+
/**
|
|
788
|
+
* TODO(FW-6931): Remove this fallback upon solving the root cause
|
|
789
|
+
* Fallback to ensure the datetime becomes ready even if
|
|
790
|
+
* IntersectionObserver never reports it as intersecting.
|
|
791
|
+
*
|
|
792
|
+
* This is primarily used in environments where the observer
|
|
793
|
+
* might not fire as expected, such as when running under
|
|
794
|
+
* synthetic tests that stub IntersectionObserver.
|
|
795
|
+
*/
|
|
796
|
+
this.ensureReadyIfVisible = () => {
|
|
797
|
+
if (this.el.classList.contains('datetime-ready')) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const rect = this.el.getBoundingClientRect();
|
|
801
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
this.initializeListeners();
|
|
805
|
+
writeTask(() => {
|
|
806
|
+
this.el.classList.add('datetime-ready');
|
|
807
|
+
});
|
|
808
|
+
};
|
|
787
809
|
this.processValue = (value) => {
|
|
788
810
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
789
811
|
const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
|
|
@@ -1101,6 +1123,17 @@ const Datetime = class {
|
|
|
1101
1123
|
* triggering the `hiddenIO` observer below.
|
|
1102
1124
|
*/
|
|
1103
1125
|
raf(() => visibleIO === null || visibleIO === void 0 ? void 0 : visibleIO.observe(intersectionTrackerRef));
|
|
1126
|
+
/**
|
|
1127
|
+
* TODO(FW-6931): Remove this fallback upon solving the root cause
|
|
1128
|
+
* Fallback: If IntersectionObserver never reports that the
|
|
1129
|
+
* datetime is visible but the host clearly has layout, ensure
|
|
1130
|
+
* we still initialize listeners and mark the component as ready.
|
|
1131
|
+
*
|
|
1132
|
+
* We schedule this after everything has had a chance to run.
|
|
1133
|
+
*/
|
|
1134
|
+
setTimeout(() => {
|
|
1135
|
+
this.ensureReadyIfVisible();
|
|
1136
|
+
}, 100);
|
|
1104
1137
|
/**
|
|
1105
1138
|
* We need to clean up listeners when the datetime is hidden
|
|
1106
1139
|
* in a popover/modal so that we can properly scroll containers
|
|
@@ -1856,7 +1889,7 @@ const Datetime = class {
|
|
|
1856
1889
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1857
1890
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1858
1891
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1859
|
-
return (h(Host, { key: '
|
|
1892
|
+
return (h(Host, { key: 'efdbc0922670a841bc667ceac392cdc1dedffd01', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
|
|
1860
1893
|
[mode]: true,
|
|
1861
1894
|
['datetime-readonly']: readonly,
|
|
1862
1895
|
['datetime-disabled']: disabled,
|
|
@@ -1866,7 +1899,7 @@ const Datetime = class {
|
|
|
1866
1899
|
[`datetime-size-${size}`]: true,
|
|
1867
1900
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1868
1901
|
[`datetime-grid`]: isGridStyle,
|
|
1869
|
-
})) }, h("div", { key: '
|
|
1902
|
+
})) }, h("div", { key: '3f8bb75fcb0baff55182ef3aa1b535eacc58d81f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1870
1903
|
}
|
|
1871
1904
|
get el() { return getElement(this); }
|
|
1872
1905
|
static get watchers() { return {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { r as registerInstance, c as createEvent, i as forceUpdate, h, d as Host, g as getElement } from './index-C8IsBmNU.js';
|
|
5
5
|
import { c as createNotchController } from './notch-controller-BwelN_JM.js';
|
|
6
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
6
7
|
import { d as debounceEvent, i as inheritAriaAttributes, b as inheritAttributes, c as componentOnReady } from './helpers-DEn3pfjm.js';
|
|
7
8
|
import { c as createSlotMutationController, g as getCounterText } from './input.utils-DrvTa8gz.js';
|
|
8
9
|
import { h as hostContext, c as createColorClasses } from './theme-DiVJyqlX.js';
|
|
@@ -230,14 +231,6 @@ const Input = class {
|
|
|
230
231
|
componentWillLoad() {
|
|
231
232
|
this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
|
|
232
233
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Checks if the input is in an invalid state based on Ionic validation classes
|
|
235
|
-
*/
|
|
236
|
-
checkInvalidState() {
|
|
237
|
-
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
238
|
-
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
239
|
-
return hasIonTouched && hasIonInvalid;
|
|
240
|
-
}
|
|
241
234
|
connectedCallback() {
|
|
242
235
|
const { el } = this;
|
|
243
236
|
this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
|
|
@@ -245,7 +238,7 @@ const Input = class {
|
|
|
245
238
|
// Watch for class changes to update validation state
|
|
246
239
|
if (typeof MutationObserver !== 'undefined') {
|
|
247
240
|
this.validationObserver = new MutationObserver(() => {
|
|
248
|
-
const newIsInvalid =
|
|
241
|
+
const newIsInvalid = checkInvalidState(el);
|
|
249
242
|
if (this.isInvalid !== newIsInvalid) {
|
|
250
243
|
this.isInvalid = newIsInvalid;
|
|
251
244
|
// Force a re-render to update aria-describedby immediately
|
|
@@ -258,7 +251,7 @@ const Input = class {
|
|
|
258
251
|
});
|
|
259
252
|
}
|
|
260
253
|
// Always set initial state
|
|
261
|
-
this.isInvalid =
|
|
254
|
+
this.isInvalid = checkInvalidState(el);
|
|
262
255
|
this.debounceChanged();
|
|
263
256
|
{
|
|
264
257
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -522,7 +515,7 @@ const Input = class {
|
|
|
522
515
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
523
516
|
*/
|
|
524
517
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
525
|
-
return (h(Host, { key: '
|
|
518
|
+
return (h(Host, { key: '97b5308021064d9e7434ef2d3d96f27045c1b0c4', class: createColorClasses(this.color, {
|
|
526
519
|
[mode]: true,
|
|
527
520
|
'has-value': hasValue,
|
|
528
521
|
'has-focus': hasFocus,
|
|
@@ -533,14 +526,14 @@ const Input = class {
|
|
|
533
526
|
'in-item': inItem,
|
|
534
527
|
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
|
535
528
|
'input-disabled': disabled,
|
|
536
|
-
}) }, h("label", { key: '
|
|
529
|
+
}) }, h("label", { key: '353f68726ce180299bd9adc81e5ff7d26a48f54f', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '2034b4bad04fc157f3298a1805819216b6f439d0', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '96bb5e30176b2bd76dfb75bfbf6c1c3d4403f4bb', name: "start" }), h("input", Object.assign({ key: '1a1d75b0e414a95c89d5a760757c33548d234aca', 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: '95f3df17b7691d9a2e7dcd4a51f16a94aa3ca36f', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
537
530
|
/**
|
|
538
531
|
* This prevents mobile browsers from
|
|
539
532
|
* blurring the input when the clear
|
|
540
533
|
* button is activated.
|
|
541
534
|
*/
|
|
542
535
|
ev.preventDefault();
|
|
543
|
-
}, onClick: this.clearTextInput }, h("ion-icon", { key: '
|
|
536
|
+
}, onClick: this.clearTextInput }, h("ion-icon", { key: '16b0af75eed50c8115fb5597f73b5fbf71c2530e', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: 'c48da0f8ddb3764ac43efa705bb4a6bb2d9cc2fd', name: "end" })), shouldRenderHighlight && h("div", { key: 'f15238481fc20de56ca7ecb6e350b3c024cc755e', class: "input-highlight" })), this.renderBottomContent()));
|
|
544
537
|
}
|
|
545
538
|
get el() { return getElement(this); }
|
|
546
539
|
static get watchers() { return {
|
|
@@ -9,7 +9,7 @@ import { c as createLockController } from './lock-controller-B-hirT0v.js';
|
|
|
9
9
|
import { g as getCapacitor } from './capacitor-CFERIeaU.js';
|
|
10
10
|
import { G as GESTURE, O as OVERLAY_GESTURE_PRIORITY, F as FOCUS_TRAP_DISABLE_CLASS, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-BymNv-BL.js';
|
|
11
11
|
import { g as getClassMap } from './theme-DiVJyqlX.js';
|
|
12
|
-
import { e as deepReady, w as waitForMount } from './index-
|
|
12
|
+
import { e as deepReady, w as waitForMount } from './index-r2D9DEro.js';
|
|
13
13
|
import { b as getIonMode } from './ionic-global-CDrldh-5.js';
|
|
14
14
|
import { KEYBOARD_DID_OPEN } from './keyboard-ywgs5efA.js';
|
|
15
15
|
import { c as createAnimation } from './animation-Dt8bGnA-.js';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { r as registerInstance, c as createEvent, e as config, f as printIonWarning, h, g as getElement, d as Host } from './index-C8IsBmNU.js';
|
|
5
5
|
import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
|
|
6
6
|
import { s as shallowEqualStringMap, l as assert } from './helpers-DEn3pfjm.js';
|
|
7
|
-
import { l as lifecycle, t as transition, s as setPageHidden, d as LIFECYCLE_WILL_UNLOAD, b as LIFECYCLE_WILL_LEAVE, c as LIFECYCLE_DID_LEAVE } from './index-
|
|
7
|
+
import { l as lifecycle, t as transition, s as setPageHidden, d as LIFECYCLE_WILL_UNLOAD, b as LIFECYCLE_WILL_LEAVE, c as LIFECYCLE_DID_LEAVE } from './index-r2D9DEro.js';
|
|
8
8
|
import { b as getIonMode } from './ionic-global-CDrldh-5.js';
|
|
9
9
|
import { a as attachComponent } from './framework-delegate-BYawdMXj.js';
|
|
10
10
|
|
|
@@ -8,7 +8,7 @@ import { g as getElementRoot, r as raf, f as addEventListener, h as hasLazyBuild
|
|
|
8
8
|
import { c as createLockController } from './lock-controller-B-hirT0v.js';
|
|
9
9
|
import { b as getIonMode, a as isPlatform } from './ionic-global-CDrldh-5.js';
|
|
10
10
|
import { g as getClassMap } from './theme-DiVJyqlX.js';
|
|
11
|
-
import { e as deepReady, w as waitForMount } from './index-
|
|
11
|
+
import { e as deepReady, w as waitForMount } from './index-r2D9DEro.js';
|
|
12
12
|
import { c as createAnimation } from './animation-Dt8bGnA-.js';
|
|
13
13
|
import './index-ZjP4CjeZ.js';
|
|
14
14
|
import './hardware-back-button-CPLxO-Ev.js';
|
|
@@ -6,6 +6,7 @@ import { f as addEventListener, m as removeEventListener, a as renderHiddenInput
|
|
|
6
6
|
import { i as isOptionSelected } from './compare-with-utils-sObYyvOy.js';
|
|
7
7
|
import { h as hostContext, c as createColorClasses } from './theme-DiVJyqlX.js';
|
|
8
8
|
import { b as getIonMode } from './ionic-global-CDrldh-5.js';
|
|
9
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
9
10
|
|
|
10
11
|
const radioIosCss = ":host{--inner-border-radius:50%;display:inline-block;position:relative;max-width:100%;min-height:inherit;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.radio-disabled){pointer-events:none}.radio-icon{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;contain:layout size style}.radio-icon,.radio-inner{-webkit-box-sizing:border-box;box-sizing:border-box}input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host(:focus){outline:none}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}.radio-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;min-height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.radio-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.radio-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between) .radio-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.radio-justify-start) .radio-wrapper{-ms-flex-pack:start;justify-content:start}:host(.radio-justify-end) .radio-wrapper{-ms-flex-pack:end;justify-content:end}:host(.radio-alignment-start) .radio-wrapper{-ms-flex-align:start;align-items:start}:host(.radio-alignment-center) .radio-wrapper{-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between),:host(.radio-justify-start),:host(.radio-justify-end),:host(.radio-alignment-start),:host(.radio-alignment-center){display:block}:host(.radio-label-placement-start) .radio-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.radio-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-end) .radio-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.radio-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.radio-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px}:host(.radio-label-placement-stacked) .radio-wrapper{-ms-flex-direction:column;flex-direction:column}:host(.radio-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host{--color-checked:var(--ion-color-primary, #0054e9)}:host(.ion-color.radio-checked) .radio-inner{border-color:var(--ion-color-base)}.item-radio.item-ios ion-label{-webkit-margin-start:0;margin-inline-start:0}.radio-inner{width:33%;height:50%}:host(.radio-checked) .radio-inner{-webkit-transform:rotate(45deg);transform:rotate(45deg);border-width:0.125rem;border-top-width:0;border-left-width:0;border-style:solid;border-color:var(--color-checked)}:host(.radio-disabled){opacity:0.3}:host(.ion-focused) .radio-icon::after{border-radius:var(--inner-border-radius);top:-8px;display:block;position:absolute;width:36px;height:36px;background:var(--ion-color-primary-tint, #1a65eb);content:\"\";opacity:0.2}:host(.ion-focused) .radio-icon::after{inset-inline-start:-9px}.native-wrapper .radio-icon{width:0.9375rem;height:1.5rem}";
|
|
11
12
|
|
|
@@ -175,6 +176,10 @@ const RadioGroup = class {
|
|
|
175
176
|
this.helperTextId = `${this.inputId}-helper-text`;
|
|
176
177
|
this.errorTextId = `${this.inputId}-error-text`;
|
|
177
178
|
this.labelId = `${this.inputId}-lbl`;
|
|
179
|
+
/**
|
|
180
|
+
* Track validation state for proper aria-live announcements.
|
|
181
|
+
*/
|
|
182
|
+
this.isInvalid = false;
|
|
178
183
|
/**
|
|
179
184
|
* If `true`, the radios can be deselected.
|
|
180
185
|
*/
|
|
@@ -256,6 +261,52 @@ const RadioGroup = class {
|
|
|
256
261
|
this.labelId = label.id = this.name + '-lbl';
|
|
257
262
|
}
|
|
258
263
|
}
|
|
264
|
+
// Watch for class changes to update validation state.
|
|
265
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
266
|
+
this.validationObserver = new MutationObserver(() => {
|
|
267
|
+
const newIsInvalid = checkInvalidState(this.el);
|
|
268
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
269
|
+
this.isInvalid = newIsInvalid;
|
|
270
|
+
/**
|
|
271
|
+
* Screen readers tend to announce changes
|
|
272
|
+
* to `aria-describedby` when the attribute
|
|
273
|
+
* is changed during a blur event for a
|
|
274
|
+
* native form control.
|
|
275
|
+
* However, the announcement can be spotty
|
|
276
|
+
* when using a non-native form control
|
|
277
|
+
* and `forceUpdate()`.
|
|
278
|
+
* This is due to `forceUpdate()` internally
|
|
279
|
+
* rescheduling the DOM update to a lower
|
|
280
|
+
* priority queue regardless if it's called
|
|
281
|
+
* inside a Promise or not, thus causing
|
|
282
|
+
* the screen reader to potentially miss the
|
|
283
|
+
* change.
|
|
284
|
+
* By using a State variable inside a Promise,
|
|
285
|
+
* it guarantees a re-render immediately at
|
|
286
|
+
* a higher priority.
|
|
287
|
+
*/
|
|
288
|
+
Promise.resolve().then(() => {
|
|
289
|
+
this.hintTextId = this.getHintTextId();
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
this.validationObserver.observe(this.el, {
|
|
294
|
+
attributes: true,
|
|
295
|
+
attributeFilter: ['class'],
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
// Always set initial state
|
|
299
|
+
this.isInvalid = checkInvalidState(this.el);
|
|
300
|
+
}
|
|
301
|
+
componentWillLoad() {
|
|
302
|
+
this.hintTextId = this.getHintTextId();
|
|
303
|
+
}
|
|
304
|
+
disconnectedCallback() {
|
|
305
|
+
// Clean up validation observer to prevent memory leaks.
|
|
306
|
+
if (this.validationObserver) {
|
|
307
|
+
this.validationObserver.disconnect();
|
|
308
|
+
this.validationObserver = undefined;
|
|
309
|
+
}
|
|
259
310
|
}
|
|
260
311
|
getRadios() {
|
|
261
312
|
return Array.from(this.el.querySelectorAll('ion-radio'));
|
|
@@ -331,16 +382,16 @@ const RadioGroup = class {
|
|
|
331
382
|
* Renders the helper text or error text values
|
|
332
383
|
*/
|
|
333
384
|
renderHintText() {
|
|
334
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
385
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
335
386
|
const hasHintText = !!helperText || !!errorText;
|
|
336
387
|
if (!hasHintText) {
|
|
337
388
|
return;
|
|
338
389
|
}
|
|
339
|
-
return (h("div", { class: "radio-group-top" }, h("div", { id: helperTextId, class: "helper-text" }, helperText), h("div", { id: errorTextId, class: "error-text" }, errorText)));
|
|
390
|
+
return (h("div", { class: "radio-group-top" }, h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null), h("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null)));
|
|
340
391
|
}
|
|
341
|
-
|
|
342
|
-
const {
|
|
343
|
-
if (
|
|
392
|
+
getHintTextId() {
|
|
393
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
394
|
+
if (isInvalid && errorText) {
|
|
344
395
|
return errorTextId;
|
|
345
396
|
}
|
|
346
397
|
if (helperText) {
|
|
@@ -352,7 +403,7 @@ const RadioGroup = class {
|
|
|
352
403
|
const { label, labelId, el, name, value } = this;
|
|
353
404
|
const mode = getIonMode(this);
|
|
354
405
|
renderHiddenInput(true, el, name, value, false);
|
|
355
|
-
return (h(Host, { key: '
|
|
406
|
+
return (h(Host, { key: 'db593b3ed511e9395e3c7bfd91b787328692cd6d', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), h("div", { key: '85045b45a0100a45f3b9a35d1c5a25ec63d525c4', class: "radio-group-wrapper" }, h("slot", { key: '53dacb87ce62398e78771fb2efaf839ab922d946' }))));
|
|
356
407
|
}
|
|
357
408
|
get el() { return getElement(this); }
|
|
358
409
|
static get watchers() { return {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { r as registerInstance, c as createEvent, f as printIonWarning, h, d as Host, g as getElement, i as forceUpdate } from './index-C8IsBmNU.js';
|
|
5
5
|
import { c as createNotchController } from './notch-controller-BwelN_JM.js';
|
|
6
6
|
import { i as isOptionSelected, c as compareOptions } from './compare-with-utils-sObYyvOy.js';
|
|
7
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
7
8
|
import { b as inheritAttributes, a as renderHiddenInput, n as focusVisibleElement } from './helpers-DEn3pfjm.js';
|
|
8
9
|
import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-BymNv-BL.js';
|
|
9
10
|
import { i as isRTL } from './dir-C53feagD.js';
|
|
@@ -43,6 +44,10 @@ const Select = class {
|
|
|
43
44
|
* is applied in both cases.
|
|
44
45
|
*/
|
|
45
46
|
this.hasFocus = false;
|
|
47
|
+
/**
|
|
48
|
+
* Track validation state for proper aria-live announcements.
|
|
49
|
+
*/
|
|
50
|
+
this.isInvalid = false;
|
|
46
51
|
/**
|
|
47
52
|
* The text to display on the cancel button.
|
|
48
53
|
*/
|
|
@@ -172,9 +177,46 @@ const Select = class {
|
|
|
172
177
|
*/
|
|
173
178
|
forceUpdate(this);
|
|
174
179
|
});
|
|
180
|
+
// Watch for class changes to update validation state.
|
|
181
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
182
|
+
this.validationObserver = new MutationObserver(() => {
|
|
183
|
+
const newIsInvalid = checkInvalidState(this.el);
|
|
184
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
185
|
+
this.isInvalid = newIsInvalid;
|
|
186
|
+
/**
|
|
187
|
+
* Screen readers tend to announce changes
|
|
188
|
+
* to `aria-describedby` when the attribute
|
|
189
|
+
* is changed during a blur event for a
|
|
190
|
+
* native form control.
|
|
191
|
+
* However, the announcement can be spotty
|
|
192
|
+
* when using a non-native form control
|
|
193
|
+
* and `forceUpdate()`.
|
|
194
|
+
* This is due to `forceUpdate()` internally
|
|
195
|
+
* rescheduling the DOM update to a lower
|
|
196
|
+
* priority queue regardless if it's called
|
|
197
|
+
* inside a Promise or not, thus causing
|
|
198
|
+
* the screen reader to potentially miss the
|
|
199
|
+
* change.
|
|
200
|
+
* By using a State variable inside a Promise,
|
|
201
|
+
* it guarantees a re-render immediately at
|
|
202
|
+
* a higher priority.
|
|
203
|
+
*/
|
|
204
|
+
Promise.resolve().then(() => {
|
|
205
|
+
this.hintTextId = this.getHintTextId();
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
this.validationObserver.observe(el, {
|
|
210
|
+
attributes: true,
|
|
211
|
+
attributeFilter: ['class'],
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
// Always set initial state
|
|
215
|
+
this.isInvalid = checkInvalidState(this.el);
|
|
175
216
|
}
|
|
176
217
|
componentWillLoad() {
|
|
177
218
|
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
|
219
|
+
this.hintTextId = this.getHintTextId();
|
|
178
220
|
}
|
|
179
221
|
componentDidLoad() {
|
|
180
222
|
/**
|
|
@@ -198,6 +240,11 @@ const Select = class {
|
|
|
198
240
|
this.notchController.destroy();
|
|
199
241
|
this.notchController = undefined;
|
|
200
242
|
}
|
|
243
|
+
// Clean up validation observer to prevent memory leaks.
|
|
244
|
+
if (this.validationObserver) {
|
|
245
|
+
this.validationObserver.disconnect();
|
|
246
|
+
this.validationObserver = undefined;
|
|
247
|
+
}
|
|
201
248
|
}
|
|
202
249
|
/**
|
|
203
250
|
* Open the select overlay. The overlay is either an alert, action sheet, or popover,
|
|
@@ -668,11 +715,11 @@ const Select = class {
|
|
|
668
715
|
}
|
|
669
716
|
renderListbox() {
|
|
670
717
|
const { disabled, inputId, isExpanded, required } = this;
|
|
671
|
-
return (h("button", { disabled: disabled, id: inputId, "aria-label": this.ariaLabel, "aria-haspopup": "dialog", "aria-expanded": `${isExpanded}`, "aria-describedby": this.
|
|
718
|
+
return (h("button", { disabled: disabled, id: inputId, "aria-label": this.ariaLabel, "aria-haspopup": "dialog", "aria-expanded": `${isExpanded}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-required": `${required}`, onFocus: this.onFocus, onBlur: this.onBlur, ref: (focusEl) => (this.focusEl = focusEl) }));
|
|
672
719
|
}
|
|
673
|
-
|
|
674
|
-
const {
|
|
675
|
-
if (
|
|
720
|
+
getHintTextId() {
|
|
721
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
722
|
+
if (isInvalid && errorText) {
|
|
676
723
|
return errorTextId;
|
|
677
724
|
}
|
|
678
725
|
if (helperText) {
|
|
@@ -684,10 +731,10 @@ const Select = class {
|
|
|
684
731
|
* Renders the helper text or error text values
|
|
685
732
|
*/
|
|
686
733
|
renderHintText() {
|
|
687
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
734
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
688
735
|
return [
|
|
689
|
-
h("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText),
|
|
690
|
-
h("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText),
|
|
736
|
+
h("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null),
|
|
737
|
+
h("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text", role: "alert" }, isInvalid ? errorText : null),
|
|
691
738
|
];
|
|
692
739
|
}
|
|
693
740
|
/**
|
|
@@ -735,7 +782,7 @@ const Select = class {
|
|
|
735
782
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
736
783
|
*/
|
|
737
784
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
|
|
738
|
-
return (h(Host, { key: '
|
|
785
|
+
return (h(Host, { key: '35b5e18e6f79a802ff2d46d1242e80ff755cc0b9', onClick: this.onClick, class: createColorClasses(this.color, {
|
|
739
786
|
[mode]: true,
|
|
740
787
|
'in-item': inItem,
|
|
741
788
|
'in-item-color': hostContext('ion-item.ion-color', el),
|
|
@@ -753,7 +800,7 @@ const Select = class {
|
|
|
753
800
|
[`select-justify-${justify}`]: justifyEnabled,
|
|
754
801
|
[`select-shape-${shape}`]: shape !== undefined,
|
|
755
802
|
[`select-label-placement-${labelPlacement}`]: true,
|
|
756
|
-
}) }, h("label", { key: '
|
|
803
|
+
}) }, h("label", { key: '6005b34a0c50bc4d7653a4276bc232ecd02e083c', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'c7e07aa81ae856c057f16275dd058f37c5670a47', class: "select-wrapper-inner" }, h("slot", { key: '7fc2deefe0424404caacdbbd9e08ed43ba55d28a', name: "start" }), h("div", { key: '157d74ee717b1bc30b5f1c233a09b0c8456aa68e', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: 'ea66db304528b82bf9317730b6dce3db2612f235', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '786eb1530b7476f0615d4e7c0bf4e7e4dc66509c', class: "select-highlight" })), this.renderBottomContent()));
|
|
757
804
|
}
|
|
758
805
|
get el() { return getElement(this); }
|
|
759
806
|
static get watchers() { return {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { r as registerInstance, c as createEvent, i as forceUpdate, w as writeTask, h, d as Host, g as getElement } from './index-C8IsBmNU.js';
|
|
5
5
|
import { c as createNotchController } from './notch-controller-BwelN_JM.js';
|
|
6
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
6
7
|
import { d as debounceEvent, i as inheritAriaAttributes, b as inheritAttributes, c as componentOnReady } from './helpers-DEn3pfjm.js';
|
|
7
8
|
import { c as createSlotMutationController, g as getCounterText } from './input.utils-DrvTa8gz.js';
|
|
8
9
|
import { h as hostContext, c as createColorClasses } from './theme-DiVJyqlX.js';
|
|
@@ -190,14 +191,6 @@ const Textarea = class {
|
|
|
190
191
|
this.el.click();
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
|
-
/**
|
|
194
|
-
* Checks if the textarea is in an invalid state based on Ionic validation classes
|
|
195
|
-
*/
|
|
196
|
-
checkValidationState() {
|
|
197
|
-
const hasIonTouched = this.el.classList.contains('ion-touched');
|
|
198
|
-
const hasIonInvalid = this.el.classList.contains('ion-invalid');
|
|
199
|
-
return hasIonTouched && hasIonInvalid;
|
|
200
|
-
}
|
|
201
194
|
connectedCallback() {
|
|
202
195
|
const { el } = this;
|
|
203
196
|
this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
|
|
@@ -205,7 +198,7 @@ const Textarea = class {
|
|
|
205
198
|
// Watch for class changes to update validation state
|
|
206
199
|
if (typeof MutationObserver !== 'undefined') {
|
|
207
200
|
this.validationObserver = new MutationObserver(() => {
|
|
208
|
-
const newIsInvalid = this.
|
|
201
|
+
const newIsInvalid = checkInvalidState(this.el);
|
|
209
202
|
if (this.isInvalid !== newIsInvalid) {
|
|
210
203
|
this.isInvalid = newIsInvalid;
|
|
211
204
|
// Force a re-render to update aria-describedby immediately
|
|
@@ -218,7 +211,7 @@ const Textarea = class {
|
|
|
218
211
|
});
|
|
219
212
|
}
|
|
220
213
|
// Always set initial state
|
|
221
|
-
this.isInvalid = this.
|
|
214
|
+
this.isInvalid = checkInvalidState(this.el);
|
|
222
215
|
this.debounceChanged();
|
|
223
216
|
{
|
|
224
217
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -482,7 +475,7 @@ const Textarea = class {
|
|
|
482
475
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
483
476
|
*/
|
|
484
477
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
485
|
-
return (h(Host, { key: '
|
|
478
|
+
return (h(Host, { key: 'a70a62d7aae3831a50acd74f60b930925ada1326', class: createColorClasses(this.color, {
|
|
486
479
|
[mode]: true,
|
|
487
480
|
'has-value': hasValue,
|
|
488
481
|
'has-focus': hasFocus,
|
|
@@ -491,7 +484,7 @@ const Textarea = class {
|
|
|
491
484
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
492
485
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
493
486
|
'textarea-disabled': disabled,
|
|
494
|
-
}) }, h("label", { key: '
|
|
487
|
+
}) }, h("label", { key: '8a2dd59a60f7469df84018eb0ede3a9ec3862703', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '1bfc368236e3da7a225a45118c27fbfc1fe5fa46', class: "textarea-wrapper-inner" }, h("div", { key: '215cbb2635ff52e31a8973376989b85e7245d40f', class: "start-slot-wrapper" }, h("slot", { key: '9f6b461cdee9d629deb695d2bea054ece2f32305', name: "start" })), h("div", { key: 'c1af35a2d5bc452bebe0b22a26d15ff52b4e9fc8', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '69a69b3cf0932baafbe37e6e846f1a571608d3f2', 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: 'c053ea8b865d0e29763aed2e4939cc9c9e374c15', class: "end-slot-wrapper" }, h("slot", { key: '930aa641833b0df54b9ea10368fc2f46d5f491f6', name: "end" }))), shouldRenderHighlight && h("div", { key: '8d12597d15f5f429d80e8272ea99e64ed924e482', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
495
488
|
}
|
|
496
489
|
get el() { return getElement(this); }
|
|
497
490
|
static get watchers() { return {
|