voyager-ionic-core 8.8.2 → 8.8.5
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-action-sheet.js +1 -1
- package/components/ion-checkbox.js +1 -1
- package/components/ion-content.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-input-otp.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-picker-column.js +1 -1
- package/components/ion-radio-group.js +1 -1
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/p-0z8QSI5b.js +4 -0
- package/components/{p-ApmKVjaE.js → p-BGHGpkPX.js} +1 -1
- package/components/p-BlNv564p.js +4 -0
- package/components/p-D-cP12ZN.js +4 -0
- package/components/p-D3Ti70Hx.js +4 -0
- package/components/{p-Bk2zuNWT.js → p-DvOO1fxp.js} +1 -1
- package/components/p-FBcnjE5W.js +4 -0
- package/components/p-SBseW5KJ.js +4 -0
- package/css/palettes/dark.always.css +1 -1
- package/css/palettes/dark.always.css.map +1 -1
- package/css/palettes/dark.class.css +1 -1
- package/css/palettes/dark.class.css.map +1 -1
- package/css/palettes/dark.system.css +1 -1
- package/css/palettes/dark.system.css.map +1 -1
- package/css/palettes/high-contrast-dark.always.css +1 -1
- package/css/palettes/high-contrast-dark.always.css.map +1 -1
- package/css/palettes/high-contrast-dark.class.css +1 -1
- package/css/palettes/high-contrast-dark.class.css.map +1 -1
- package/css/palettes/high-contrast-dark.system.css +1 -1
- package/css/palettes/high-contrast-dark.system.css.map +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +4 -4
- package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
- package/dist/cjs/ion-checkbox.cjs.entry.js +39 -32
- package/dist/cjs/ion-datetime_3.cjs.entry.js +17 -6
- package/dist/cjs/ion-input-otp.cjs.entry.js +21 -6
- package/dist/cjs/ion-modal.cjs.entry.js +99 -45
- package/dist/cjs/ion-picker-column.cjs.entry.js +4 -4
- package/dist/cjs/ion-radio_2.cjs.entry.js +13 -1
- package/dist/cjs/ion-select-modal.cjs.entry.js +18 -7
- package/dist/cjs/ion-select_3.cjs.entry.js +18 -7
- package/dist/collection/components/action-sheet/action-sheet.js +4 -4
- package/dist/collection/components/checkbox/checkbox.js +39 -32
- package/dist/collection/components/content/content.css +1 -1
- package/dist/collection/components/datetime/datetime.js +17 -6
- package/dist/collection/components/input-otp/input-otp.js +21 -6
- package/dist/collection/components/modal/modal.js +73 -44
- package/dist/collection/components/modal/safe-area-utils.js +27 -2
- package/dist/collection/components/picker-column/picker-column.js +5 -5
- package/dist/collection/components/radio-group/radio-group.js +13 -1
- package/dist/collection/components/radio-group/test/fixtures.js +2 -2
- package/dist/collection/components/select-modal/select-modal.js +18 -7
- package/dist/collection/components/select-modal/test/fixtures.js +4 -0
- package/dist/collection/components/select-popover/select-popover.js +18 -7
- package/dist/collection/components/select-popover/test/fixtures.js +4 -0
- package/dist/docs.json +1 -1
- package/dist/esm/ion-action-sheet.entry.js +4 -4
- package/dist/esm/ion-app_8.entry.js +1 -1
- package/dist/esm/ion-checkbox.entry.js +39 -32
- package/dist/esm/ion-datetime_3.entry.js +17 -6
- package/dist/esm/ion-input-otp.entry.js +21 -6
- package/dist/esm/ion-modal.entry.js +99 -45
- package/dist/esm/ion-picker-column.entry.js +5 -5
- package/dist/esm/ion-radio_2.entry.js +13 -1
- package/dist/esm/ion-select-modal.entry.js +18 -7
- package/dist/esm/ion-select_3.entry.js +18 -7
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-078037da.entry.js +4 -0
- package/dist/ionic/p-23ec35e4.entry.js +4 -0
- package/dist/ionic/p-268a3397.entry.js +4 -0
- package/dist/ionic/p-28a9e720.entry.js +4 -0
- package/dist/ionic/p-4c67ce4c.entry.js +4 -0
- package/dist/ionic/p-87125490.entry.js +4 -0
- package/dist/ionic/{p-4dd5e8e0.entry.js → p-8fda6a62.entry.js} +1 -1
- package/dist/ionic/{p-9eac4eb1.entry.js → p-aa812c4b.entry.js} +1 -1
- package/dist/ionic/p-cb27fe68.entry.js +4 -0
- package/dist/ionic/p-ce2edb36.entry.js +4 -0
- package/dist/types/components/checkbox/checkbox.d.ts +0 -1
- package/dist/types/components/datetime/datetime.d.ts +1 -0
- package/dist/types/components/modal/modal.d.ts +41 -3
- package/dist/types/components/modal/safe-area-utils.d.ts +16 -0
- package/dist/types/components/radio-group/test/fixtures.d.ts +1 -1
- package/dist/types/components/select-modal/select-modal.d.ts +1 -0
- package/dist/types/components/select-modal/test/fixtures.d.ts +1 -0
- package/dist/types/components/select-popover/select-popover.d.ts +1 -0
- package/dist/types/components/select-popover/test/fixtures.d.ts +1 -0
- package/hydrate/index.js +199 -87
- package/hydrate/index.mjs +199 -87
- package/package.json +4 -4
- package/components/p-1KVKSLu5.js +0 -4
- package/components/p-BI7WNErr.js +0 -4
- package/components/p-C7AoMl7c.js +0 -4
- package/components/p-D6pdfDIA.js +0 -4
- package/components/p-cvHphHJA.js +0 -4
- package/components/p-e-EDj2CO.js +0 -4
- package/dist/ionic/p-2d4eb1b4.entry.js +0 -4
- package/dist/ionic/p-3e143d1d.entry.js +0 -4
- package/dist/ionic/p-51c11c47.entry.js +0 -4
- package/dist/ionic/p-5681dde4.entry.js +0 -4
- package/dist/ionic/p-9fae83d8.entry.js +0 -4
- package/dist/ionic/p-c744307d.entry.js +0 -4
- package/dist/ionic/p-cb78f5a0.entry.js +0 -4
- package/dist/ionic/p-e6c5f060.entry.js +0 -4
|
@@ -473,7 +473,7 @@ const ActionSheet = class {
|
|
|
473
473
|
if (isRadio) {
|
|
474
474
|
htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
|
|
475
475
|
}
|
|
476
|
-
return (index.h("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass(b)), { 'action-sheet-selected': isActiveRadio }), onClick: () => {
|
|
476
|
+
return (index.h("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass(b)), (isRadio && { 'action-sheet-selected': isActiveRadio })), onClick: () => {
|
|
477
477
|
if (isRadio) {
|
|
478
478
|
this.selectRadioButton(b);
|
|
479
479
|
}
|
|
@@ -488,12 +488,12 @@ const ActionSheet = class {
|
|
|
488
488
|
const cancelButton = allButtons.find((b) => b.role === 'cancel');
|
|
489
489
|
const buttons = allButtons.filter((b) => b.role !== 'cancel');
|
|
490
490
|
const headerID = `action-sheet-${overlayIndex}-header`;
|
|
491
|
-
return (index.h(index.Host, Object.assign({ key: '
|
|
491
|
+
return (index.h(index.Host, Object.assign({ key: 'a56ee2ab59c763036140dbd10306a708c26e3c17', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
|
|
492
492
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
493
|
-
}, class: Object.assign(Object.assign({ [mode]: true }, theme.getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), index.h("ion-backdrop", { key: '
|
|
493
|
+
}, class: Object.assign(Object.assign({ [mode]: true }, theme.getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), index.h("ion-backdrop", { key: 'c32eb4281fd6348c7d3989a3f509c211263048e6', tappable: this.backdropDismiss }), index.h("div", { key: '7f0123114a876fc7cfff3cfb564aded4a7017797', tabindex: "0", "aria-hidden": "true" }), index.h("div", { key: '645b1d5fde39a8907f21983d66e6ecb7a99aa05d', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, index.h("div", { key: 'a78fb02848462d1a4f9356ac4fa1c43a2e5d90e4', class: "action-sheet-container" }, index.h("div", { key: '5e846f53e067b211b985d6e1512b72b9d7c1a3aa', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (index.h("div", { key: 'a90a0e096e1b2fa78b9adb9253c0a517f16e62cb', id: headerID, class: {
|
|
494
494
|
'action-sheet-title': true,
|
|
495
495
|
'action-sheet-has-sub-title': this.subHeader !== undefined,
|
|
496
|
-
} }, header, this.subHeader && index.h("div", { key: '
|
|
496
|
+
} }, header, this.subHeader && index.h("div", { key: '40f00b12341625c548546de1885b9c9d93bc169c', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (index.h("div", { key: 'ef6974cb63089623df08087274b82745443cee8c', class: "action-sheet-group action-sheet-group-cancel" }, index.h("button", Object.assign({ key: 'b02911a6491d60f9dcb5da7d942392a9e96552c1' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass(cancelButton), onClick: () => this.buttonClick(cancelButton) }), index.h("span", { key: '1187433e676eda55e52b5ae328a8e68bba22deb6', class: "action-sheet-button-inner" }, cancelButton.icon && (index.h("ion-icon", { key: '079ab2a6bd40b996950053617f1c1c8207ecb1f1', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && index.h("ion-ripple-effect", { key: '3bc473add8ac299f202f8c359d26708872c02f52' })))))), index.h("div", { key: '9b1ae7b4e3649e9b85632f0d65627ca81499e68d', tabindex: "0", "aria-hidden": "true" })));
|
|
497
497
|
}
|
|
498
498
|
get el() { return index.getElement(this); }
|
|
499
499
|
static get watchers() { return {
|
|
@@ -159,7 +159,7 @@ Buttons.style = {
|
|
|
159
159
|
md: buttonsMdCss()
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
-
const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
|
|
162
|
+
const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom) + var(--ion-content-safe-area-padding-bottom, 0px));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
|
|
163
163
|
|
|
164
164
|
const Content = class {
|
|
165
165
|
constructor(hostRef) {
|
|
@@ -112,48 +112,55 @@ const Checkbox = class {
|
|
|
112
112
|
this.onDivLabelClick = (ev) => {
|
|
113
113
|
ev.stopPropagation();
|
|
114
114
|
};
|
|
115
|
-
this.onSlotChange = () => {
|
|
116
|
-
this.hasLabelContent = this.el.textContent !== '';
|
|
117
|
-
};
|
|
118
115
|
}
|
|
119
116
|
connectedCallback() {
|
|
120
117
|
const { el } = this;
|
|
121
|
-
// Watch for class changes to update validation state.
|
|
122
118
|
if (typeof MutationObserver !== 'undefined') {
|
|
123
|
-
this.validationObserver = new MutationObserver(() => {
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
this.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
119
|
+
this.validationObserver = new MutationObserver((mutations) => {
|
|
120
|
+
// Watch for label content changes
|
|
121
|
+
if (mutations.some((mutation) => mutation.type === 'characterData' || mutation.type === 'childList')) {
|
|
122
|
+
this.hasLabelContent = this.el.textContent !== '';
|
|
123
|
+
}
|
|
124
|
+
// Watch for class changes to update validation state.
|
|
125
|
+
if (mutations.some((mutation) => mutation.type === 'attributes' && mutation.target === el)) {
|
|
126
|
+
const newIsInvalid = validity.checkInvalidState(el);
|
|
127
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
128
|
+
this.isInvalid = newIsInvalid;
|
|
129
|
+
/**
|
|
130
|
+
* Screen readers tend to announce changes
|
|
131
|
+
* to `aria-describedby` when the attribute
|
|
132
|
+
* is changed during a blur event for a
|
|
133
|
+
* native form control.
|
|
134
|
+
* However, the announcement can be spotty
|
|
135
|
+
* when using a non-native form control
|
|
136
|
+
* and `forceUpdate()`.
|
|
137
|
+
* This is due to `forceUpdate()` internally
|
|
138
|
+
* rescheduling the DOM update to a lower
|
|
139
|
+
* priority queue regardless if it's called
|
|
140
|
+
* inside a Promise or not, thus causing
|
|
141
|
+
* the screen reader to potentially miss the
|
|
142
|
+
* change.
|
|
143
|
+
* By using a State variable inside a Promise,
|
|
144
|
+
* it guarantees a re-render immediately at
|
|
145
|
+
* a higher priority.
|
|
146
|
+
*/
|
|
147
|
+
Promise.resolve().then(() => {
|
|
148
|
+
this.hintTextId = this.getHintTextId();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
});
|
|
150
153
|
this.validationObserver.observe(el, {
|
|
151
154
|
attributes: true,
|
|
152
155
|
attributeFilter: ['class'],
|
|
156
|
+
characterData: true,
|
|
157
|
+
childList: true,
|
|
158
|
+
subtree: true,
|
|
153
159
|
});
|
|
154
160
|
}
|
|
155
161
|
// Always set initial state
|
|
156
162
|
this.isInvalid = validity.checkInvalidState(el);
|
|
163
|
+
this.hasLabelContent = this.el.textContent !== '';
|
|
157
164
|
}
|
|
158
165
|
componentWillLoad() {
|
|
159
166
|
this.inheritedAttributes = Object.assign({}, helpers.inheritAriaAttributes(this.el));
|
|
@@ -203,7 +210,7 @@ const Checkbox = class {
|
|
|
203
210
|
helpers.renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
204
211
|
// The host element must have a checkbox role to ensure proper VoiceOver
|
|
205
212
|
// support in Safari for accessibility.
|
|
206
|
-
return (index.h(index.Host, { key: '
|
|
213
|
+
return (index.h(index.Host, { key: '0da370f94c5cdf3b08bc9008395558334a300f35', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.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: theme.createColorClasses(color, {
|
|
207
214
|
[mode]: true,
|
|
208
215
|
'in-item': theme.hostContext('ion-item', el),
|
|
209
216
|
'checkbox-checked': checked,
|
|
@@ -213,10 +220,10 @@ const Checkbox = class {
|
|
|
213
220
|
[`checkbox-justify-${justify}`]: justify !== undefined,
|
|
214
221
|
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
|
|
215
222
|
[`checkbox-label-placement-${labelPlacement}`]: true,
|
|
216
|
-
}) }, index.h("label", { key: '
|
|
223
|
+
}) }, index.h("label", { key: '991f1763356671230af119a5fbdc22d0a39974e7', class: "checkbox-wrapper", htmlFor: inputId }, index.h("input", Object.assign({ key: '982f8a7f84d013b272b17607936355d2b6c251f4', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), index.h("div", { key: 'c8f9e8baa20ac68e69fd3c6fcf0e7a26a1084d83', class: {
|
|
217
224
|
'label-text-wrapper': true,
|
|
218
225
|
'label-text-wrapper-hidden': !this.hasLabelContent,
|
|
219
|
-
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, index.h("slot", { key: '
|
|
226
|
+
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, index.h("slot", { key: '6018205e0a73dec826c7881d687f1c2ca8dcb0ab' }), this.renderHintText()), index.h("div", { key: '57530b9d6ff59ee7ab98f960cd65d66ee87cfd1d', class: "native-wrapper" }, index.h("svg", { key: '63d719154ff44459e9ca448e3f5d7de94d9ab248', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
|
|
220
227
|
}
|
|
221
228
|
getSVGPath(mode, indeterminate) {
|
|
222
229
|
let path = indeterminate ? (index.h("path", { d: "M6 12L18 12", part: "mark" })) : (index.h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
|
|
@@ -813,6 +813,12 @@ const Datetime = class {
|
|
|
813
813
|
this.el.classList.add('datetime-ready');
|
|
814
814
|
});
|
|
815
815
|
};
|
|
816
|
+
this.loadTimeoutCleanup = () => {
|
|
817
|
+
if (this.loadTimeout) {
|
|
818
|
+
clearTimeout(this.loadTimeout);
|
|
819
|
+
this.loadTimeout = undefined;
|
|
820
|
+
}
|
|
821
|
+
};
|
|
816
822
|
this.processValue = (value) => {
|
|
817
823
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
818
824
|
const valueToProcess = hasValue ? data.parseDate(value) : this.defaultParts;
|
|
@@ -960,9 +966,10 @@ const Datetime = class {
|
|
|
960
966
|
if (!prevMonth) {
|
|
961
967
|
return;
|
|
962
968
|
}
|
|
969
|
+
const left = prevMonth.offsetWidth * 2;
|
|
963
970
|
calendarBodyRef.scrollTo({
|
|
964
971
|
top: 0,
|
|
965
|
-
left:
|
|
972
|
+
left: left * (dir.isRTL(this.el) ? 1 : -1),
|
|
966
973
|
behavior: 'smooth',
|
|
967
974
|
});
|
|
968
975
|
};
|
|
@@ -1084,15 +1091,16 @@ const Datetime = class {
|
|
|
1084
1091
|
}
|
|
1085
1092
|
connectedCallback() {
|
|
1086
1093
|
this.clearFocusVisible = focusVisible.startFocusVisible(this.el).destroy;
|
|
1094
|
+
this.loadTimeout = setTimeout(() => {
|
|
1095
|
+
this.ensureReadyIfVisible();
|
|
1096
|
+
}, 100);
|
|
1087
1097
|
}
|
|
1088
1098
|
disconnectedCallback() {
|
|
1089
1099
|
if (this.clearFocusVisible) {
|
|
1090
1100
|
this.clearFocusVisible();
|
|
1091
1101
|
this.clearFocusVisible = undefined;
|
|
1092
1102
|
}
|
|
1093
|
-
|
|
1094
|
-
clearTimeout(this.loadTimeout);
|
|
1095
|
-
}
|
|
1103
|
+
this.loadTimeoutCleanup();
|
|
1096
1104
|
}
|
|
1097
1105
|
initializeListeners() {
|
|
1098
1106
|
this.initializeCalendarListener();
|
|
@@ -1140,7 +1148,10 @@ const Datetime = class {
|
|
|
1140
1148
|
* we still initialize listeners and mark the component as ready.
|
|
1141
1149
|
*
|
|
1142
1150
|
* We schedule this after everything has had a chance to run.
|
|
1151
|
+
*
|
|
1152
|
+
* We also clean up the load timeout to ensure that we don't have multiple timeouts running.
|
|
1143
1153
|
*/
|
|
1154
|
+
this.loadTimeoutCleanup();
|
|
1144
1155
|
this.loadTimeout = setTimeout(() => {
|
|
1145
1156
|
this.ensureReadyIfVisible();
|
|
1146
1157
|
}, 100);
|
|
@@ -1899,7 +1910,7 @@ const Datetime = class {
|
|
|
1899
1910
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1900
1911
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1901
1912
|
helpers.renderHiddenInput(true, el, name, data.formatValue(value), disabled);
|
|
1902
|
-
return (index.h(index.Host, { key: '
|
|
1913
|
+
return (index.h(index.Host, { key: '59e0811aa273e88dfb8e4b703e6824088a457380', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, theme.createColorClasses(color, {
|
|
1903
1914
|
[mode]: true,
|
|
1904
1915
|
['datetime-readonly']: readonly,
|
|
1905
1916
|
['datetime-disabled']: disabled,
|
|
@@ -1909,7 +1920,7 @@ const Datetime = class {
|
|
|
1909
1920
|
[`datetime-size-${size}`]: true,
|
|
1910
1921
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1911
1922
|
[`datetime-grid`]: isGridStyle,
|
|
1912
|
-
})) }, index.h("div", { key: '
|
|
1923
|
+
})) }, index.h("div", { key: '3753ff3dde3085070916c3de83687a219a49e553', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1913
1924
|
}
|
|
1914
1925
|
get el() { return index.getElement(this); }
|
|
1915
1926
|
static get watchers() { return {
|
|
@@ -142,9 +142,18 @@ const InputOTP = class {
|
|
|
142
142
|
* - Tab: Allows normal tab navigation between components
|
|
143
143
|
*/
|
|
144
144
|
this.onKeyDown = (index) => (event) => {
|
|
145
|
-
const { length } = this;
|
|
145
|
+
const { disabled, length, readonly } = this;
|
|
146
146
|
const rtl = dir.isRTL(this.el);
|
|
147
147
|
const input = event.target;
|
|
148
|
+
if (disabled) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (readonly) {
|
|
152
|
+
if (event.key === 'Backspace' || event.key === 'Delete') {
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
148
157
|
// Meta shortcuts are used to copy, paste, and select text
|
|
149
158
|
// We don't want to handle these keys here
|
|
150
159
|
const metaShortcuts = ['a', 'c', 'v', 'x', 'r', 'z', 'y'];
|
|
@@ -207,10 +216,13 @@ const InputOTP = class {
|
|
|
207
216
|
*/
|
|
208
217
|
this.onInput = (index) => (event) => {
|
|
209
218
|
var _a, _b;
|
|
210
|
-
const { length, validKeyPattern } = this;
|
|
219
|
+
const { disabled, length, readonly, validKeyPattern } = this;
|
|
211
220
|
const input = event.target;
|
|
212
221
|
const value = input.value;
|
|
213
222
|
const previousValue = this.previousInputValues[index] || '';
|
|
223
|
+
if (disabled || readonly) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
214
226
|
// 1. Autofill handling
|
|
215
227
|
// If the length of the value increases by more than 1 from the previous
|
|
216
228
|
// value, treat this as autofill. This is to prevent the case where the
|
|
@@ -329,8 +341,11 @@ const InputOTP = class {
|
|
|
329
341
|
*/
|
|
330
342
|
this.onPaste = (event) => {
|
|
331
343
|
var _a, _b;
|
|
332
|
-
const { inputRefs, length, validKeyPattern } = this;
|
|
344
|
+
const { disabled, inputRefs, length, readonly, validKeyPattern } = this;
|
|
333
345
|
event.preventDefault();
|
|
346
|
+
if (disabled || readonly) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
334
349
|
const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
|
|
335
350
|
// If there is no pasted text, still emit the input change event
|
|
336
351
|
// because this is how the native input element behaves
|
|
@@ -617,7 +632,7 @@ const InputOTP = class {
|
|
|
617
632
|
const tabbableIndex = this.getTabbableIndex();
|
|
618
633
|
const pattern = this.getPattern();
|
|
619
634
|
const hasDescription = ((_b = (_a = el.querySelector('.input-otp-description')) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== '';
|
|
620
|
-
return (index.h(index.Host, { key: '
|
|
635
|
+
return (index.h(index.Host, { key: '5c1386ae6b8038ec33ca94fd818c9353b1b37f75', class: theme.createColorClasses(color, {
|
|
621
636
|
[mode]: true,
|
|
622
637
|
'has-focus': hasFocus,
|
|
623
638
|
[`input-otp-size-${size}`]: true,
|
|
@@ -625,10 +640,10 @@ const InputOTP = class {
|
|
|
625
640
|
[`input-otp-fill-${fill}`]: true,
|
|
626
641
|
'input-otp-disabled': disabled,
|
|
627
642
|
'input-otp-readonly': readonly,
|
|
628
|
-
}) }, index.h("div", Object.assign({ key: '
|
|
643
|
+
}) }, index.h("div", Object.assign({ key: '9a19129688e55095f8386826c73ef3f9744becff', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index$1) => (index.h(index.Fragment, null, index.h("div", { class: "native-wrapper" }, index.h("input", { class: "native-input", id: `${inputId}-${index$1}`, "aria-label": `Input ${index$1 + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index$1 === tabbableIndex ? 0 : -1, value: inputValues[index$1] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index$1] = el), onInput: this.onInput(index$1), onBlur: this.onBlur, onFocus: this.onFocus(index$1), onKeyDown: this.onKeyDown(index$1), onPaste: this.onPaste })), this.showSeparator(index$1) && index.h("div", { class: "input-otp-separator" }))))), index.h("div", { key: '7853819c3610c4691191f1836b947bf4ec17939d', class: {
|
|
629
644
|
'input-otp-description': true,
|
|
630
645
|
'input-otp-description-hidden': !hasDescription,
|
|
631
|
-
} }, index.h("slot", { key: '
|
|
646
|
+
} }, index.h("slot", { key: 'f4674d47d3d3991f21a0a79321ebc323968071dc' }))));
|
|
632
647
|
}
|
|
633
648
|
get el() { return index.getElement(this); }
|
|
634
649
|
static get watchers() { return {
|
|
@@ -1648,6 +1648,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1648
1648
|
const MODAL_INSET_MIN_WIDTH = 768;
|
|
1649
1649
|
const MODAL_INSET_MIN_HEIGHT = 600;
|
|
1650
1650
|
const EDGE_THRESHOLD = 5;
|
|
1651
|
+
/**
|
|
1652
|
+
* CSS values for `--width` / `--height` that are treated as fullscreen
|
|
1653
|
+
* (modal touches the corresponding screen edges). Empty string means the
|
|
1654
|
+
* property was not overridden. See `hasCustomModalDimensions()`.
|
|
1655
|
+
*/
|
|
1656
|
+
const FULLSCREEN_SIZE_VALUES = new Set(['', '100%', '100vw', '100vh', '100dvw', '100dvh', '100svw', '100svh']);
|
|
1651
1657
|
/**
|
|
1652
1658
|
* Cache for resolved root safe-area-top value, invalidated once per frame.
|
|
1653
1659
|
*/
|
|
@@ -1696,6 +1702,22 @@ const getRootSafeAreaTop = () => {
|
|
|
1696
1702
|
}
|
|
1697
1703
|
return value;
|
|
1698
1704
|
};
|
|
1705
|
+
/**
|
|
1706
|
+
* True when the modal host declares BOTH a non-fullscreen `--width` AND a
|
|
1707
|
+
* non-fullscreen `--height` (i.e. a centered-dialog-like modal that doesn't
|
|
1708
|
+
* touch any screen edge).
|
|
1709
|
+
*
|
|
1710
|
+
* The conservative "both axes" check avoids mis-zeroing safe-area for
|
|
1711
|
+
* partial-custom modals where the modal still touches top/bottom edges
|
|
1712
|
+
* (e.g. only `--width` overridden). Partial cases fall through to the
|
|
1713
|
+
* existing position-based post-animation correction.
|
|
1714
|
+
*/
|
|
1715
|
+
const hasCustomModalDimensions = (hostEl) => {
|
|
1716
|
+
const styles = getComputedStyle(hostEl);
|
|
1717
|
+
const width = styles.getPropertyValue('--width').trim();
|
|
1718
|
+
const height = styles.getPropertyValue('--height').trim();
|
|
1719
|
+
return !FULLSCREEN_SIZE_VALUES.has(width) && !FULLSCREEN_SIZE_VALUES.has(height);
|
|
1720
|
+
};
|
|
1699
1721
|
/**
|
|
1700
1722
|
* Returns the initial safe-area configuration based on modal type.
|
|
1701
1723
|
* This is called before animation starts and uses configuration-based prediction.
|
|
@@ -1730,8 +1752,11 @@ const getInitialSafeAreaConfig = (context) => {
|
|
|
1730
1752
|
}
|
|
1731
1753
|
// On viewports that meet the centered dialog media query breakpoints,
|
|
1732
1754
|
// regular modals render as centered dialogs (not fullscreen), so they
|
|
1733
|
-
// don't touch any screen edges and don't need safe-area insets.
|
|
1734
|
-
|
|
1755
|
+
// don't touch any screen edges and don't need safe-area insets. Also
|
|
1756
|
+
// applies to phone viewports when the modal declares custom --width and
|
|
1757
|
+
// --height; these don't touch screen edges either, so the initial
|
|
1758
|
+
// prediction must be zero to avoid a post-animation correction flash.
|
|
1759
|
+
if (isCenteredDialogViewport() || context.hasCustomDimensions) {
|
|
1735
1760
|
return {
|
|
1736
1761
|
top: '0px',
|
|
1737
1762
|
bottom: '0px',
|
|
@@ -2033,12 +2058,10 @@ const Modal = class {
|
|
|
2033
2058
|
// since the viewport may have crossed the centered-dialog breakpoint.
|
|
2034
2059
|
if (!context.isSheetModal && !context.isCardModal) {
|
|
2035
2060
|
this.updateSafeAreaOverrides();
|
|
2036
|
-
// Re-evaluate fullscreen safe-area padding: clear first, then re-apply
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
this.applyFullscreenSafeArea();
|
|
2061
|
+
// Re-evaluate fullscreen safe-area padding: clear first, then re-apply.
|
|
2062
|
+
const { contentEl, hasFooter } = this.findContentAndFooter();
|
|
2063
|
+
this.clearContentSafeAreaPadding(contentEl);
|
|
2064
|
+
this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
|
|
2042
2065
|
}
|
|
2043
2066
|
}, 50); // Debounce to avoid excessive calls during active resizing
|
|
2044
2067
|
}
|
|
@@ -2785,6 +2808,11 @@ const Modal = class {
|
|
|
2785
2808
|
}
|
|
2786
2809
|
/**
|
|
2787
2810
|
* Creates the context object for safe-area utilities.
|
|
2811
|
+
*
|
|
2812
|
+
* `hasCustomDimensions` is only set by `setInitialSafeAreaOverrides()`
|
|
2813
|
+
* because it is only read by `getInitialSafeAreaConfig()`. Other callers
|
|
2814
|
+
* (resize handler, post-animation update, fullscreen-padding apply) would
|
|
2815
|
+
* pay a `getComputedStyle()` cost for a value they never consult.
|
|
2788
2816
|
*/
|
|
2789
2817
|
getSafeAreaContext() {
|
|
2790
2818
|
return {
|
|
@@ -2806,7 +2834,7 @@ const Modal = class {
|
|
|
2806
2834
|
* sheets to prevent header content from getting double-offset padding).
|
|
2807
2835
|
*/
|
|
2808
2836
|
setInitialSafeAreaOverrides() {
|
|
2809
|
-
const context = this.getSafeAreaContext();
|
|
2837
|
+
const context = Object.assign(Object.assign({}, this.getSafeAreaContext()), { hasCustomDimensions: hasCustomModalDimensions(this.el) });
|
|
2810
2838
|
const safeAreaConfig = getInitialSafeAreaConfig(context);
|
|
2811
2839
|
applySafeAreaOverrides(this.el, safeAreaConfig);
|
|
2812
2840
|
// Set the internal offset property with the resolved root safe-area-top value
|
|
@@ -2846,59 +2874,85 @@ const Modal = class {
|
|
|
2846
2874
|
applySafeAreaOverrides(el, safeAreaConfig);
|
|
2847
2875
|
}
|
|
2848
2876
|
/**
|
|
2849
|
-
* Applies
|
|
2850
|
-
*
|
|
2877
|
+
* Applies safe-area-bottom scroll padding to ion-content inside
|
|
2878
|
+
* fullscreen modals that have no ion-footer. This prevents content
|
|
2879
|
+
* from being hidden behind the system navigation bar while keeping
|
|
2880
|
+
* the modal background edge-to-edge (no visible gap).
|
|
2851
2881
|
*/
|
|
2852
2882
|
applyFullscreenSafeArea() {
|
|
2853
|
-
const { wrapperEl, el } = this;
|
|
2854
|
-
if (!wrapperEl)
|
|
2855
|
-
return;
|
|
2856
2883
|
const context = this.getSafeAreaContext();
|
|
2857
2884
|
if (context.isSheetModal || context.isCardModal)
|
|
2858
2885
|
return;
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2886
|
+
const { contentEl, hasFooter } = this.findContentAndFooter();
|
|
2887
|
+
this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
|
|
2888
|
+
}
|
|
2889
|
+
/**
|
|
2890
|
+
* Sets --ion-content-safe-area-padding-bottom on the given ion-content
|
|
2891
|
+
* when no footer is present, so ion-content's .inner-scroll includes
|
|
2892
|
+
* safe-area-bottom in its scroll padding. This keeps the modal background
|
|
2893
|
+
* edge-to-edge while ensuring content scrolls clear of the system nav bar.
|
|
2894
|
+
*
|
|
2895
|
+
* --ion-content-safe-area-padding-bottom is an internal CSS property used
|
|
2896
|
+
* only by this code path. It is not part of ion-content's public API and
|
|
2897
|
+
* should not be set by consumers. The default of 0px makes it a no-op
|
|
2898
|
+
* when unset, which is the expected state for ion-content used outside of
|
|
2899
|
+
* a fullscreen modal without a footer.
|
|
2900
|
+
*/
|
|
2901
|
+
applyFullscreenSafeAreaTo(contentEl, hasFooter) {
|
|
2902
|
+
// Only apply for standard Ionic layouts (has ion-content but no
|
|
2903
|
+
// ion-footer). When a footer is present it handles its own safe-area
|
|
2904
|
+
// padding. Custom modals with raw HTML are developer-controlled.
|
|
2905
|
+
if (!contentEl || hasFooter)
|
|
2906
|
+
return;
|
|
2907
|
+
contentEl.style.setProperty('--ion-content-safe-area-padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
|
|
2908
|
+
}
|
|
2909
|
+
/**
|
|
2910
|
+
* Removes the internal --ion-content-safe-area-padding-bottom property
|
|
2911
|
+
* from an already-located ion-content. Callers do their own
|
|
2912
|
+
* findContentAndFooter() so they can also read hasFooter if needed.
|
|
2913
|
+
*/
|
|
2914
|
+
clearContentSafeAreaPadding(contentEl) {
|
|
2915
|
+
if (!contentEl)
|
|
2916
|
+
return;
|
|
2917
|
+
contentEl.style.removeProperty('--ion-content-safe-area-padding-bottom');
|
|
2918
|
+
}
|
|
2919
|
+
/**
|
|
2920
|
+
* Finds ion-content and ion-footer among direct children and one level of
|
|
2921
|
+
* grandchildren (for wrapped components like <app-footer><ion-footer>).
|
|
2922
|
+
*
|
|
2923
|
+
* Intentionally does NOT use findIonContent() or querySelector() because
|
|
2924
|
+
* those search the full subtree and would match ion-content inside nested
|
|
2925
|
+
* routes/pages. We only want direct slot children (+ one wrapper level).
|
|
2926
|
+
*
|
|
2927
|
+
* Uses a manual loop instead of querySelector(':scope > ...') because
|
|
2928
|
+
* Stencil's mock-doc (used in spec tests) does not support :scope.
|
|
2929
|
+
*/
|
|
2930
|
+
findContentAndFooter() {
|
|
2931
|
+
let contentEl = null;
|
|
2865
2932
|
let hasFooter = false;
|
|
2866
|
-
for (const child of Array.from(el.children)) {
|
|
2933
|
+
for (const child of Array.from(this.el.children)) {
|
|
2867
2934
|
if (child.tagName === 'ION-CONTENT')
|
|
2868
|
-
|
|
2935
|
+
contentEl = child;
|
|
2869
2936
|
if (child.tagName === 'ION-FOOTER')
|
|
2870
2937
|
hasFooter = true;
|
|
2871
2938
|
for (const grandchild of Array.from(child.children)) {
|
|
2872
|
-
if (grandchild.tagName === 'ION-CONTENT')
|
|
2873
|
-
|
|
2939
|
+
if (grandchild.tagName === 'ION-CONTENT' && !contentEl)
|
|
2940
|
+
contentEl = grandchild;
|
|
2874
2941
|
if (grandchild.tagName === 'ION-FOOTER')
|
|
2875
2942
|
hasFooter = true;
|
|
2876
2943
|
}
|
|
2877
2944
|
}
|
|
2878
|
-
|
|
2879
|
-
// but no ion-footer). Custom modals with raw HTML are fully
|
|
2880
|
-
// developer-controlled and should not be modified.
|
|
2881
|
-
if (!hasContent || hasFooter)
|
|
2882
|
-
return;
|
|
2883
|
-
// Reduce wrapper height by safe-area and add equivalent padding so the
|
|
2884
|
-
// total visual size stays the same but the flex content area shrinks.
|
|
2885
|
-
// Using height + padding instead of box-sizing: border-box avoids
|
|
2886
|
-
// breaking custom modals that set --border-width (border-box would
|
|
2887
|
-
// include the border inside the height, changing the layout).
|
|
2888
|
-
wrapperEl.style.setProperty('height', 'calc(var(--height) - var(--ion-safe-area-bottom, 0px))');
|
|
2889
|
-
wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
|
|
2945
|
+
return { contentEl, hasFooter };
|
|
2890
2946
|
}
|
|
2891
2947
|
/**
|
|
2892
|
-
* Clears all safe-area overrides and padding
|
|
2948
|
+
* Clears all safe-area overrides and padding.
|
|
2893
2949
|
*/
|
|
2894
2950
|
cleanupSafeAreaOverrides() {
|
|
2895
2951
|
clearSafeAreaOverrides(this.el);
|
|
2896
2952
|
// Remove internal sheet offset property
|
|
2897
2953
|
this.el.style.removeProperty('--ion-modal-offset-top');
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
2901
|
-
}
|
|
2954
|
+
const { contentEl } = this.findContentAndFooter();
|
|
2955
|
+
this.clearContentSafeAreaPadding(contentEl);
|
|
2902
2956
|
}
|
|
2903
2957
|
render() {
|
|
2904
2958
|
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
|
|
@@ -2907,20 +2961,20 @@ const Modal = class {
|
|
|
2907
2961
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
2908
2962
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
2909
2963
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
2910
|
-
return (index$3.h(index$3.Host, Object.assign({ key: '
|
|
2964
|
+
return (index$3.h(index$3.Host, Object.assign({ key: '4bf38aa67df9a3f977163bba5423960bbafd16de', "no-router": true,
|
|
2911
2965
|
// Allow the modal to be navigable when the handle is focusable
|
|
2912
2966
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
2913
2967
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
2914
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '
|
|
2968
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '866da40cc5fc8d3e36637098fb3066a5bc9f4e0f', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: '5a2a05514ea8592c8feb0465e504aa7c7af17963', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: '4d327115306451f57d190b06ab8cbb6191a6f1d7',
|
|
2915
2969
|
/*
|
|
2916
2970
|
role and aria-modal must be used on the
|
|
2917
2971
|
same element. They must also be set inside the
|
|
2918
2972
|
shadow DOM otherwise ion-button will not be highlighted
|
|
2919
2973
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
2920
2974
|
*/
|
|
2921
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: '
|
|
2975
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: 'd1882835cc049232c0d957e3ba1e79676a07d179', class: "modal-handle",
|
|
2922
2976
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
2923
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '
|
|
2977
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '81dc58b09cf7d7022b04cd170f53113604364d5e', onSlotchange: this.onSlotChange }))));
|
|
2924
2978
|
}
|
|
2925
2979
|
get el() { return index$3.getElement(this); }
|
|
2926
2980
|
static get watchers() { return {
|
|
@@ -450,7 +450,7 @@ const PickerColumn = class {
|
|
|
450
450
|
* Because this initial call to scrollActiveItemIntoView has to fire before
|
|
451
451
|
* the scroll listener is set up, we need to manage the active class manually.
|
|
452
452
|
*/
|
|
453
|
-
const oldActive =
|
|
453
|
+
const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
|
|
454
454
|
if (oldActive) {
|
|
455
455
|
this.setPickerItemActiveState(oldActive, false);
|
|
456
456
|
}
|
|
@@ -550,14 +550,14 @@ const PickerColumn = class {
|
|
|
550
550
|
render() {
|
|
551
551
|
const { color, disabled, isActive, numericInput } = this;
|
|
552
552
|
const mode = ionicGlobal.getIonMode(this);
|
|
553
|
-
return (index.h(index.Host, { key: '
|
|
553
|
+
return (index.h(index.Host, { key: '234c96a501d7ac413b9b0ea56b33017681e25b40', class: theme.createColorClasses(color, {
|
|
554
554
|
[mode]: true,
|
|
555
555
|
['picker-column-active']: isActive,
|
|
556
556
|
['picker-column-numeric-input']: numericInput,
|
|
557
557
|
['picker-column-disabled']: disabled,
|
|
558
|
-
}) }, index.h("slot", { key: '
|
|
558
|
+
}) }, index.h("slot", { key: '9dc15ea0601ddd2cb2e0a745e91e036a8bd96f8b', name: "prefix" }), index.h("div", { key: 'de4fe28ee4bc46b7c0420d6ab0df0e7809443da9', class: "picker-opts", ref: (el) => {
|
|
559
559
|
this.scrollEl = el;
|
|
560
|
-
}, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, index.h("div", { key: '
|
|
560
|
+
}, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, index.h("div", { key: '5297617462cc30e9444039ae032d8bdf718349af', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), index.h("div", { key: '55ea39ef867bcb1a11a912d52ecd20cb886c5fb3', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), index.h("div", { key: '3496730ce6182ebfd33e0ee4bafc130feb575a31', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), index.h("slot", { key: '44c3628aa957d60f799dc7019f72fe8b676c7843' }), index.h("div", { key: '5a1809f6c949678a67e0d4b5bfe93ea335c0161d', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), index.h("div", { key: '98fd57f1c66dbaebc2db2dd5da142671b3159fd1', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), index.h("div", { key: '85590708abddfa885994e549deac64866fec938f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), index.h("slot", { key: 'bb7e674f543696a80fcbfb1f68f2e975826898a6', name: "suffix" })));
|
|
561
561
|
}
|
|
562
562
|
get el() { return index.getElement(this); }
|
|
563
563
|
static get watchers() { return {
|
|
@@ -375,6 +375,18 @@ const RadioGroup = class {
|
|
|
375
375
|
// to the bottom of the screen
|
|
376
376
|
ev.preventDefault();
|
|
377
377
|
}
|
|
378
|
+
// Inside a select interface, Enter commits the focused radio
|
|
379
|
+
// value (matching native <select>). The !ev.repeat guard stops
|
|
380
|
+
// a held Enter on the triggering ion-select from re-committing
|
|
381
|
+
// once focus lands in the opened popover/modal.
|
|
382
|
+
if (ev.key === 'Enter' && inSelectInterface && !ev.repeat) {
|
|
383
|
+
const previousValue = this.value;
|
|
384
|
+
this.value = current.value;
|
|
385
|
+
if (previousValue !== this.value) {
|
|
386
|
+
this.emitValueChange(ev);
|
|
387
|
+
}
|
|
388
|
+
ev.preventDefault();
|
|
389
|
+
}
|
|
378
390
|
}
|
|
379
391
|
}
|
|
380
392
|
/** @internal */
|
|
@@ -407,7 +419,7 @@ const RadioGroup = class {
|
|
|
407
419
|
const { label, labelId, el, name, value } = this;
|
|
408
420
|
const mode = ionicGlobal.getIonMode(this);
|
|
409
421
|
helpers.renderHiddenInput(true, el, name, value, false);
|
|
410
|
-
return (index.h(index.Host, { key: '
|
|
422
|
+
return (index.h(index.Host, { key: '377e4aa3a656cc84b742f9d7a7d4be65d20c69f5', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), index.h("slot", { key: 'c3187a2497773b4f15cea3b413b036502bcec8c0' })));
|
|
411
423
|
}
|
|
412
424
|
get el() { return index.getElement(this); }
|
|
413
425
|
static get watchers() { return {
|