voyager-ionic-core 8.8.10 → 8.8.17
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/index.js +1 -1
- package/components/ion-accordion.js +1 -1
- package/components/ion-action-sheet.js +1 -1
- package/components/ion-alert.js +1 -1
- package/components/ion-app.js +1 -1
- package/components/ion-back-button.js +1 -1
- package/components/ion-breadcrumb.js +1 -1
- package/components/ion-button.js +1 -1
- package/components/ion-card.js +1 -1
- package/components/ion-checkbox.js +1 -1
- package/components/ion-content.js +1 -1
- package/components/ion-datetime-button.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-fab-button.js +1 -1
- package/components/ion-footer.js +1 -1
- package/components/ion-header.js +1 -1
- package/components/ion-img.js +1 -1
- package/components/ion-infinite-scroll.js +1 -1
- package/components/ion-input-otp.js +1 -1
- package/components/ion-input-password-toggle.js +1 -1
- package/components/ion-input.js +1 -1
- package/components/ion-item-options.js +1 -1
- package/components/ion-item-sliding.js +1 -1
- package/components/ion-item.js +1 -1
- package/components/ion-loading.js +1 -1
- package/components/ion-menu-button.js +1 -1
- package/components/ion-menu-toggle.js +1 -1
- package/components/ion-menu.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-nav.js +1 -1
- package/components/ion-picker-column-option.js +1 -1
- package/components/ion-picker-column.js +1 -1
- package/components/ion-picker-legacy-column.js +1 -1
- package/components/ion-picker-legacy.js +1 -1
- package/components/ion-picker.js +1 -1
- package/components/ion-popover.js +1 -1
- package/components/ion-progress-bar.js +1 -1
- package/components/ion-radio-group.js +1 -1
- package/components/ion-radio.js +1 -1
- package/components/ion-range.js +1 -1
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-refresher.js +1 -1
- package/components/ion-reorder-group.js +1 -1
- package/components/ion-router-outlet.js +1 -1
- package/components/ion-router.js +1 -1
- package/components/ion-searchbar.js +1 -1
- package/components/ion-segment-button.js +1 -1
- package/components/ion-segment.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/ion-tab-button.js +1 -1
- package/components/ion-tab.js +1 -1
- package/components/ion-textarea.js +1 -1
- package/components/ion-toast.js +1 -1
- package/components/ion-toggle.js +1 -1
- package/components/{p-CtukzcyX.js → p-A3O24YmY.js} +1 -1
- package/components/{p-CU5rbWAW.js → p-ABkNVeU9.js} +1 -1
- package/components/{p-BT_5jSqG.js → p-B-JJgYSG.js} +1 -1
- package/components/p-BB42Mlnr.js +4 -0
- package/components/{p-lE_JGpHD.js → p-BMI53wYL.js} +1 -1
- package/components/p-BkKAANMJ.js +4 -0
- package/components/p-BlIAuGv2.js +4 -0
- package/components/{p-Bth-EzJ0.js → p-Bnsn6KaP.js} +1 -1
- package/components/p-BsBCoGa-.js +4 -0
- package/components/{p-BnqQlm7c.js → p-CQGnMY3n.js} +1 -1
- package/components/{p-DNQI6d-L.js → p-C_hpsif8.js} +1 -1
- package/components/p-Cf2jSDS8.js +4 -0
- package/components/{p-C4t5ymfq.js → p-ChIZKXUu.js} +1 -1
- package/components/p-CkMSOsFF.js +4 -0
- package/components/p-CsNJ1ULL.js +4 -0
- package/components/{p-BsPelv04.js → p-CzCbeKys.js} +1 -1
- package/components/{p-BjfgFSSR.js → p-D-aHdMxW.js} +1 -1
- package/components/p-D0d8qTwj.js +4 -0
- package/components/{p-Baq1XyAy.js → p-D3xo7hqU.js} +1 -1
- package/components/{p-nQi4oKcG.js → p-DCnGU1fF.js} +1 -1
- package/components/p-DGZpx6KJ.js +4 -0
- package/components/p-DGvrK8dD.js +4 -0
- package/components/p-DHTSTb52.js +4 -0
- package/components/{p-BirPFsRD.js → p-DJZp0KTQ.js} +1 -1
- package/components/{p-ijF0iCrA.js → p-DRugphUN.js} +1 -1
- package/components/{p-0NRupjzW.js → p-DV5mPYQS.js} +1 -1
- package/components/{p-C1aScSTo.js → p-DWkAgceV.js} +1 -1
- package/components/{p-DDWp95gH.js → p-KEFO0w3i.js} +1 -1
- package/components/{p-Ciz1-FuE.js → p-Osve4qkc.js} +1 -1
- package/components/{p-dhLYXa7A.js → p-SLS1rDZM.js} +1 -1
- package/components/{p-D5Ubpm7D.js → p-VWbRkLT7.js} +1 -1
- package/components/{p-BTPfOxsU.js → p-aJ6PBUvj.js} +1 -1
- package/components/{p-DnL1c9_X.js → p-oD4kcBRX.js} +1 -1
- package/components/{p-CI3ncNZm.js → p-scxfI1Dd.js} +1 -1
- package/components/p-yzCsOZE2.js +4 -0
- package/dist/cjs/{data-DLTUw-KF.js → format-PxvGiOik.js} +8 -532
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
- package/dist/cjs/ion-alert.cjs.entry.js +1 -1
- package/dist/cjs/ion-button_2.cjs.entry.js +7 -3
- package/dist/cjs/ion-checkbox.cjs.entry.js +17 -7
- package/dist/cjs/ion-datetime-button.cjs.entry.js +17 -15
- package/dist/cjs/ion-datetime_3.cjs.entry.js +616 -75
- package/dist/cjs/ion-fab_3.cjs.entry.js +87 -9
- package/dist/cjs/ion-input-otp.cjs.entry.js +3 -3
- package/dist/cjs/ion-item_8.cjs.entry.js +84 -4
- package/dist/cjs/ion-loading.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-modal.cjs.entry.js +35 -9
- package/dist/cjs/ion-popover.cjs.entry.js +1 -1
- package/dist/cjs/ion-radio_2.cjs.entry.js +16 -7
- package/dist/cjs/ion-refresher_2.cjs.entry.js +31 -4
- package/dist/cjs/ion-searchbar.cjs.entry.js +26 -5
- package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
- package/dist/cjs/ion-select_3.cjs.entry.js +5 -4
- package/dist/cjs/ion-tab_2.cjs.entry.js +20 -13
- package/dist/cjs/ion-toast.cjs.entry.js +1 -1
- package/dist/cjs/ion-toggle.cjs.entry.js +25 -6
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/item-multiple-inputs-D-gyg57c.js +38 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{overlays-TbKsuC-K.js → overlays-DdtIYQUH.js} +24 -1
- package/dist/collection/components/button/button.js +7 -3
- package/dist/collection/components/checkbox/checkbox.ios.css +18 -0
- package/dist/collection/components/checkbox/checkbox.js +16 -7
- package/dist/collection/components/checkbox/checkbox.md.css +18 -0
- package/dist/collection/components/datetime/datetime.js +51 -6
- package/dist/collection/components/datetime-button/datetime-button.js +8 -7
- package/dist/collection/components/fab-button/fab-button.js +114 -10
- package/dist/collection/components/input-otp/input-otp.js +3 -3
- package/dist/collection/components/item/item.ios.css +11 -0
- package/dist/collection/components/item/item.js +85 -4
- package/dist/collection/components/item/item.md.css +11 -0
- package/dist/collection/components/modal/gestures/sheet.js +7 -0
- package/dist/collection/components/modal/gestures/swipe-to-close.js +7 -0
- package/dist/collection/components/modal/modal.ios.css +8 -0
- package/dist/collection/components/modal/modal.js +18 -6
- package/dist/collection/components/modal/modal.md.css +8 -0
- package/dist/collection/components/radio/radio.ios.css +11 -15
- package/dist/collection/components/radio/radio.js +15 -7
- package/dist/collection/components/radio/radio.md.css +11 -11
- package/dist/collection/components/refresher/refresher.js +31 -4
- package/dist/collection/components/searchbar/searchbar.js +26 -5
- package/dist/collection/components/select/select.js +4 -3
- package/dist/collection/components/tab/tab.js +20 -13
- package/dist/collection/components/toggle/toggle.ios.css +12 -4
- package/dist/collection/components/toggle/toggle.js +24 -6
- package/dist/collection/components/toggle/toggle.md.css +42 -5
- package/dist/collection/utils/forms/index.js +1 -0
- package/dist/collection/utils/forms/item-multiple-inputs.js +33 -0
- package/dist/collection/utils/overlays.js +24 -1
- package/dist/collection/utils/test/playwright/apply-keyboard-focus.js +25 -0
- package/dist/collection/utils/test/playwright/drag-element.js +15 -0
- package/dist/collection/utils/test/playwright/index.js +1 -0
- package/dist/docs.json +40 -1
- package/dist/esm/{data-DZI70dKr.js → format-CAmvpAez.js} +1 -524
- package/dist/esm/index.js +1 -1
- package/dist/esm/ion-action-sheet.entry.js +1 -1
- package/dist/esm/ion-alert.entry.js +1 -1
- package/dist/esm/ion-button_2.entry.js +7 -3
- package/dist/esm/ion-checkbox.entry.js +19 -9
- package/dist/esm/ion-datetime-button.entry.js +9 -7
- package/dist/esm/ion-datetime_3.entry.js +550 -9
- package/dist/esm/ion-fab_3.entry.js +89 -11
- package/dist/esm/ion-input-otp.entry.js +3 -3
- package/dist/esm/ion-item_8.entry.js +84 -4
- package/dist/esm/ion-loading.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +1 -1
- package/dist/esm/ion-modal.entry.js +35 -9
- package/dist/esm/ion-popover.entry.js +1 -1
- package/dist/esm/ion-radio_2.entry.js +17 -8
- package/dist/esm/ion-refresher_2.entry.js +31 -4
- package/dist/esm/ion-searchbar.entry.js +26 -5
- package/dist/esm/ion-select-modal.entry.js +1 -1
- package/dist/esm/ion-select_3.entry.js +5 -4
- package/dist/esm/ion-tab_2.entry.js +20 -13
- package/dist/esm/ion-toast.entry.js +1 -1
- package/dist/esm/ion-toggle.entry.js +27 -8
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/item-multiple-inputs-DlNuqNJm.js +36 -0
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{overlays-TbiM4mdr.js → overlays-Dg0q2_tJ.js} +25 -2
- package/dist/html.html-data.json +4 -0
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-30bf9737.entry.js → p-0dc33652.entry.js} +1 -1
- package/dist/ionic/p-10e833ef.entry.js +4 -0
- package/dist/ionic/p-21eb76d5.entry.js +4 -0
- package/dist/ionic/{p-4dc1c33c.entry.js → p-2a05aa64.entry.js} +1 -1
- package/dist/ionic/p-2b204c59.entry.js +4 -0
- package/dist/ionic/p-2fa58e80.entry.js +4 -0
- package/dist/ionic/{p-94f2a736.entry.js → p-34586ead.entry.js} +1 -1
- package/dist/ionic/p-4654ae1c.entry.js +4 -0
- package/dist/ionic/{p-8d6fd502.entry.js → p-4745f534.entry.js} +1 -1
- package/dist/ionic/p-4ac4f3d6.entry.js +4 -0
- package/dist/ionic/p-5018dfc8.entry.js +4 -0
- package/dist/ionic/{p-00dbb17e.entry.js → p-5eb8e86d.entry.js} +1 -1
- package/dist/ionic/{p-e847a888.entry.js → p-65ebdf1b.entry.js} +1 -1
- package/dist/ionic/p-7c319341.entry.js +4 -0
- package/dist/ionic/p-829367ed.entry.js +4 -0
- package/dist/ionic/{p-aa5d6b8f.entry.js → p-9f9db3a2.entry.js} +1 -1
- package/dist/ionic/p-C0eMdTCW.js +4 -0
- package/dist/ionic/p-D-3ycHmd.js +4 -0
- package/dist/ionic/p-DqN5EA2O.js +4 -0
- package/dist/ionic/p-aaeedb6b.entry.js +4 -0
- package/dist/ionic/p-bfc9bb0f.entry.js +4 -0
- package/dist/ionic/p-c38b648e.entry.js +4 -0
- package/dist/ionic/{p-3a541154.entry.js → p-ca2ab74d.entry.js} +1 -1
- package/dist/ionic/p-d889ff6d.entry.js +4 -0
- package/dist/types/components/checkbox/checkbox.d.ts +1 -0
- package/dist/types/components/datetime/datetime.d.ts +8 -0
- package/dist/types/components/fab-button/fab-button.d.ts +15 -0
- package/dist/types/components/item/item.d.ts +19 -0
- package/dist/types/components/radio/radio.d.ts +1 -0
- package/dist/types/components/searchbar/searchbar.d.ts +1 -0
- package/dist/types/components/tab/tab.d.ts +1 -1
- package/dist/types/components/toggle/toggle.d.ts +1 -0
- package/dist/types/components.d.ts +15 -2
- package/dist/types/utils/forms/index.d.ts +1 -0
- package/dist/types/utils/forms/item-multiple-inputs.d.ts +13 -0
- package/dist/types/utils/test/playwright/apply-keyboard-focus.d.ts +16 -0
- package/dist/types/utils/test/playwright/index.d.ts +1 -0
- package/hydrate/index.js +411 -87
- package/hydrate/index.mjs +411 -87
- package/package.json +5 -5
- package/components/p-5bE_Wz4Y.js +0 -4
- package/components/p-B60hm8Qv.js +0 -4
- package/components/p-BAYYcg3o.js +0 -4
- package/components/p-BjoEPDW5.js +0 -4
- package/components/p-C2lKgrXx.js +0 -4
- package/components/p-D7bSXQD3.js +0 -4
- package/components/p-DIE4pXMl.js +0 -4
- package/components/p-W5nO8mX_.js +0 -4
- package/components/p-W9CZ2mWX.js +0 -4
- package/components/p-XlSIJDJ-.js +0 -4
- package/components/p-ryqmO0B-.js +0 -4
- package/dist/ionic/p-0d005398.entry.js +0 -4
- package/dist/ionic/p-1ae21e4c.entry.js +0 -4
- package/dist/ionic/p-2f55dc1a.entry.js +0 -4
- package/dist/ionic/p-3a126bca.entry.js +0 -4
- package/dist/ionic/p-3a7d1e91.entry.js +0 -4
- package/dist/ionic/p-81ea5652.entry.js +0 -4
- package/dist/ionic/p-8c8eee7d.entry.js +0 -4
- package/dist/ionic/p-9a65ac7f.entry.js +0 -4
- package/dist/ionic/p-DAAFkPFT.js +0 -4
- package/dist/ionic/p-a21add2f.entry.js +0 -4
- package/dist/ionic/p-e686695b.entry.js +0 -4
- package/dist/ionic/p-ec090e0a.entry.js +0 -4
- package/dist/ionic/p-fabcce6c.entry.js +0 -4
- package/dist/ionic/p-facfde02.entry.js +0 -4
- package/dist/ionic/p-xOfi7-Zn.js +0 -4
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { Host, forceUpdate, h } from "@stencil/core";
|
|
4
|
+
import { Build, Host, forceUpdate, h } from "@stencil/core";
|
|
5
5
|
import { inheritAttributes, raf } from "../../utils/helpers";
|
|
6
6
|
import { createColorClasses, hostContext, openURL } from "../../utils/theme";
|
|
7
7
|
import { chevronForward } from "ionicons/icons";
|
|
8
8
|
import { getIonMode } from "../../global/ionic-global";
|
|
9
|
+
const INDICATOR_CONTROL_SELECTOR = 'ion-checkbox, ion-radio, ion-toggle';
|
|
9
10
|
/**
|
|
10
11
|
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
|
11
12
|
*
|
|
@@ -23,9 +24,11 @@ export class Item {
|
|
|
23
24
|
this.labelColorStyles = {};
|
|
24
25
|
this.itemStyles = new Map();
|
|
25
26
|
this.inheritedAriaAttributes = {};
|
|
27
|
+
this.didLoad = false;
|
|
26
28
|
this.multipleInputs = false;
|
|
27
29
|
this.focusable = true;
|
|
28
30
|
this.isInteractive = false;
|
|
31
|
+
this.hasSlottedIndicatorControl = false;
|
|
29
32
|
/**
|
|
30
33
|
* If `true`, a button tag will be rendered and the item will be tappable.
|
|
31
34
|
*/
|
|
@@ -51,6 +54,7 @@ export class Item {
|
|
|
51
54
|
this.updateInteractivityOnSlotChange = () => {
|
|
52
55
|
this.setIsInteractive();
|
|
53
56
|
this.setMultipleInputs();
|
|
57
|
+
this.setHasSlottedIndicatorControl();
|
|
54
58
|
};
|
|
55
59
|
}
|
|
56
60
|
buttonChanged() {
|
|
@@ -92,6 +96,14 @@ export class Item {
|
|
|
92
96
|
}
|
|
93
97
|
connectedCallback() {
|
|
94
98
|
this.hasStartEl();
|
|
99
|
+
/**
|
|
100
|
+
* `componentDidLoad` doesn't run again when the item is moved, so re-arm the
|
|
101
|
+
* observer and re-read the light DOM, which may have changed while detached.
|
|
102
|
+
*/
|
|
103
|
+
if (this.didLoad) {
|
|
104
|
+
this.watchForIndicatorControls();
|
|
105
|
+
this.updateInteractivityOnSlotChange();
|
|
106
|
+
}
|
|
95
107
|
}
|
|
96
108
|
componentWillLoad() {
|
|
97
109
|
this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']);
|
|
@@ -100,8 +112,17 @@ export class Item {
|
|
|
100
112
|
raf(() => {
|
|
101
113
|
this.setMultipleInputs();
|
|
102
114
|
this.setIsInteractive();
|
|
115
|
+
this.setHasSlottedIndicatorControl();
|
|
103
116
|
this.focusable = this.isFocusable();
|
|
104
117
|
});
|
|
118
|
+
this.watchForIndicatorControls();
|
|
119
|
+
this.didLoad = true;
|
|
120
|
+
}
|
|
121
|
+
disconnectedCallback() {
|
|
122
|
+
if (this.indicatorControlObserver) {
|
|
123
|
+
this.indicatorControlObserver.disconnect();
|
|
124
|
+
this.indicatorControlObserver = undefined;
|
|
125
|
+
}
|
|
105
126
|
}
|
|
106
127
|
totalNestedInputs() {
|
|
107
128
|
// The following elements have a clickable cover that is relative to the entire item
|
|
@@ -135,6 +156,50 @@ export class Item {
|
|
|
135
156
|
const { covers, inputs, clickables } = this.totalNestedInputs();
|
|
136
157
|
this.isInteractive = covers.length > 0 || inputs.length > 0 || clickables.length > 0;
|
|
137
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* `slotchange` only fires for nodes assigned directly to a slot, so a control
|
|
161
|
+
* inside a slotted wrapper (`<div><ion-toggle>`) never reaches
|
|
162
|
+
* `updateInteractivityOnSlotChange`. The light DOM is observed instead.
|
|
163
|
+
*
|
|
164
|
+
* The callback runs the whole handler because a control below a wrapper can also
|
|
165
|
+
* make the item multi-input, which is what decides whether the controls draw
|
|
166
|
+
* their own indicator at all.
|
|
167
|
+
*
|
|
168
|
+
* `:host(:has())` would avoid the observer, but the `:has()` fallback in
|
|
169
|
+
* `core.scss` is still open as FW-6106 and it's unreliable for slotted content
|
|
170
|
+
* in Android WebView. Worth revisiting when FW-6106 closes.
|
|
171
|
+
*/
|
|
172
|
+
watchForIndicatorControls() {
|
|
173
|
+
var _a;
|
|
174
|
+
if (!Build.isBrowser || typeof MutationObserver === 'undefined') {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// `Node.moveBefore` relocates the item without either callback firing, so
|
|
178
|
+
// never leave a previous observer behind
|
|
179
|
+
(_a = this.indicatorControlObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
180
|
+
this.indicatorControlObserver = new MutationObserver((records) => {
|
|
181
|
+
// The subtree observer also fires for text and hidden input churn, so only
|
|
182
|
+
// re-read the DOM when a control was added or removed
|
|
183
|
+
if (records.some(touchesIndicatorControl)) {
|
|
184
|
+
this.updateInteractivityOnSlotChange();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
this.indicatorControlObserver.observe(this.el, { childList: true, subtree: true });
|
|
188
|
+
}
|
|
189
|
+
// These controls paint a focus indicator that overhangs their own bounds, and
|
|
190
|
+
// only the default slot is clipped, so only a control there needs extra room.
|
|
191
|
+
setHasSlottedIndicatorControl() {
|
|
192
|
+
const controls = this.el.querySelectorAll(INDICATOR_CONTROL_SELECTOR);
|
|
193
|
+
this.hasSlottedIndicatorControl = Array.from(controls).some((control) => {
|
|
194
|
+
// The control isn't always a direct child, so walk up to the element the item
|
|
195
|
+
// slots, which is the one carrying the slot name.
|
|
196
|
+
let slotted = control;
|
|
197
|
+
while (slotted !== null && slotted.parentElement !== this.el) {
|
|
198
|
+
slotted = slotted.parentElement;
|
|
199
|
+
}
|
|
200
|
+
return slotted !== null && !slotted.getAttribute('slot');
|
|
201
|
+
});
|
|
202
|
+
}
|
|
138
203
|
// If the item contains an input including a checkbox, datetime, select, or radio
|
|
139
204
|
// then the item will have a clickable input cover that covers the item
|
|
140
205
|
// that should get the hover, focused and activated states UNLESS it has multiple
|
|
@@ -236,7 +301,13 @@ export class Item {
|
|
|
236
301
|
* However, other form controls such as checkboxes and radios do.
|
|
237
302
|
*/
|
|
238
303
|
const firstInteractiveNeedsPointerCursor = firstInteractive !== undefined && !['ION-INPUT', 'ION-TEXTAREA'].includes(firstInteractive.tagName);
|
|
239
|
-
|
|
304
|
+
/**
|
|
305
|
+
* A control in a single-input item defers its indicator to the item, so there's
|
|
306
|
+
* nothing to clip and nothing to make room for. It draws its own indicator in a
|
|
307
|
+
* multi-input item, and in a clickable item, which is a second tab stop.
|
|
308
|
+
*/
|
|
309
|
+
const slottedIndicatorNeedsRoom = this.hasSlottedIndicatorControl && (multipleInputs || this.isClickable());
|
|
310
|
+
return (h(Host, { key: '0dc161ad7ac2fdedc5005015fceb34ed176010a6', "aria-disabled": ariaDisabled, class: Object.assign(Object.assign(Object.assign({}, childStyles), labelColorStyles), createColorClasses(this.color, {
|
|
240
311
|
item: true,
|
|
241
312
|
[mode]: true,
|
|
242
313
|
'item-lines-default': lines === undefined,
|
|
@@ -245,10 +316,11 @@ export class Item {
|
|
|
245
316
|
'item-disabled': disabled,
|
|
246
317
|
'in-list': inList,
|
|
247
318
|
'item-multiple-inputs': this.multipleInputs,
|
|
319
|
+
'item-focus-indicator-room': slottedIndicatorNeedsRoom,
|
|
248
320
|
'ion-activatable': canActivate,
|
|
249
321
|
'ion-focusable': this.focusable,
|
|
250
322
|
'item-rtl': document.dir === 'rtl',
|
|
251
|
-
})), role: inList ? 'listitem' : null }, h(TagType, Object.assign({ key: '
|
|
323
|
+
})), role: inList ? 'listitem' : null }, h(TagType, Object.assign({ key: 'd42583cf62133b2553de2e7a5357168640bb1834' }, attrs, inheritedAriaAttributes, { class: "item-native", part: "native", disabled: disabled }, clickFn), h("slot", { key: 'bd805ce49946cd52280d1c4b370104ee2472f1e2', name: "start", onSlotchange: this.updateInteractivityOnSlotChange }), h("div", { key: '0de589f9c5c13c31b6c8838566a7ad6f78f81028', class: "item-inner", part: "inner" }, h("div", { key: 'faaf6a39e072fb352753c645736ab1f47c2d7d25', class: "input-wrapper", part: "container" }, h("slot", { key: '70a34c31de29a0786a14b4a7d3156ba8d4d92eb4', onSlotchange: this.updateInteractivityOnSlotChange })), h("slot", { key: 'c8e764b62c5c30f67750896741ca266b741d5999', name: "end", onSlotchange: this.updateInteractivityOnSlotChange }), showDetail && (h("ion-icon", { key: 'af006856d8c4ed69174534261344215957cc751a', icon: detailIcon, lazy: false, class: "item-detail-icon", part: "detail-icon", "aria-hidden": "true", "flip-rtl": detailIcon === chevronForward }))), canActivate && mode === 'md' && h("ion-ripple-effect", { key: 'e5e151bafedd38feb8f71a387a0059aa1e9e90de' }))));
|
|
252
324
|
}
|
|
253
325
|
static get is() { return "ion-item"; }
|
|
254
326
|
static get encapsulation() { return "shadow"; }
|
|
@@ -543,7 +615,8 @@ export class Item {
|
|
|
543
615
|
return {
|
|
544
616
|
"multipleInputs": {},
|
|
545
617
|
"focusable": {},
|
|
546
|
-
"isInteractive": {}
|
|
618
|
+
"isInteractive": {},
|
|
619
|
+
"hasSlottedIndicatorControl": {}
|
|
547
620
|
};
|
|
548
621
|
}
|
|
549
622
|
static get elementRef() { return "el"; }
|
|
@@ -569,3 +642,11 @@ export class Item {
|
|
|
569
642
|
}];
|
|
570
643
|
}
|
|
571
644
|
}
|
|
645
|
+
const isIndicatorControl = (node) => {
|
|
646
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
const el = node;
|
|
650
|
+
return el.matches(INDICATOR_CONTROL_SELECTOR) || el.querySelector(INDICATOR_CONTROL_SELECTOR) !== null;
|
|
651
|
+
};
|
|
652
|
+
const touchesIndicatorControl = (record) => Array.from(record.addedNodes).some(isIndicatorControl) || Array.from(record.removedNodes).some(isIndicatorControl);
|
|
@@ -387,6 +387,17 @@ a {
|
|
|
387
387
|
flex-direction: column;
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
:host(.item-focus-indicator-room) .input-wrapper {
|
|
391
|
+
-webkit-margin-start: -12px;
|
|
392
|
+
margin-inline-start: -12px;
|
|
393
|
+
-webkit-margin-end: -12px;
|
|
394
|
+
margin-inline-end: -12px;
|
|
395
|
+
-webkit-padding-start: 12px;
|
|
396
|
+
padding-inline-start: 12px;
|
|
397
|
+
-webkit-padding-end: 12px;
|
|
398
|
+
padding-inline-end: 12px;
|
|
399
|
+
}
|
|
400
|
+
|
|
390
401
|
:host(.item-multiple-inputs) ::slotted(ion-checkbox),
|
|
391
402
|
:host(.item-multiple-inputs) ::slotted(ion-datetime),
|
|
392
403
|
:host(.item-multiple-inputs) ::slotted(ion-radio) {
|
|
@@ -224,6 +224,13 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
224
224
|
return true;
|
|
225
225
|
};
|
|
226
226
|
const onStart = (detail) => {
|
|
227
|
+
var _a;
|
|
228
|
+
/**
|
|
229
|
+
* Firefox automatically selects the header text during drag
|
|
230
|
+
* due to the focusable wrapper (tabindex="-1"). Remove any
|
|
231
|
+
* selection that may have occurred.
|
|
232
|
+
*/
|
|
233
|
+
(_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
|
|
227
234
|
/**
|
|
228
235
|
* If canDismiss is anything other than `true`
|
|
229
236
|
* then users should be able to swipe down
|
|
@@ -96,7 +96,14 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
|
|
|
96
96
|
return false;
|
|
97
97
|
};
|
|
98
98
|
const onStart = (detail) => {
|
|
99
|
+
var _a;
|
|
99
100
|
const { deltaY } = detail;
|
|
101
|
+
/**
|
|
102
|
+
* Firefox automatically selects the header text during drag
|
|
103
|
+
* due to the focusable wrapper (tabindex="-1"). Remove any
|
|
104
|
+
* selection that may have occurred.
|
|
105
|
+
*/
|
|
106
|
+
(_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
|
|
100
107
|
/**
|
|
101
108
|
* Get the initial scrollY value so
|
|
102
109
|
* that we can correctly reset the scrollY
|
|
@@ -126,6 +126,14 @@ ion-backdrop {
|
|
|
126
126
|
z-index: 10;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* The wrapper receives programmatic focus for screen readers but should not
|
|
131
|
+
* show a visible focus ring, which is meant only for keyboard navigation.
|
|
132
|
+
*/
|
|
133
|
+
.modal-wrapper {
|
|
134
|
+
outline: none;
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
.modal-shadow {
|
|
130
138
|
position: absolute;
|
|
131
139
|
background: transparent;
|
|
@@ -191,9 +191,15 @@ export class Modal {
|
|
|
191
191
|
* if it exists and is focusable, otherwise let the focus trap handle it.
|
|
192
192
|
*/
|
|
193
193
|
this.onModalFocus = (ev) => {
|
|
194
|
+
var _a;
|
|
194
195
|
const { dragHandleEl, el } = this;
|
|
195
|
-
|
|
196
|
-
|
|
196
|
+
/**
|
|
197
|
+
* Shadow DOM focus is retargeted to the host, so `ev.target === el` is also
|
|
198
|
+
* true when a shadow child (the dialog wrapper present() focuses) is focused.
|
|
199
|
+
* shadowRoot's activeElement is null only when the host was focused directly,
|
|
200
|
+
* so redirect to the handle only then and leave present()'s wrapper focus intact.
|
|
201
|
+
*/
|
|
202
|
+
if (ev.target === el && ((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement) == null && dragHandleEl && dragHandleEl.tabIndex !== -1) {
|
|
197
203
|
dragHandleEl.focus();
|
|
198
204
|
}
|
|
199
205
|
};
|
|
@@ -1162,20 +1168,26 @@ export class Modal {
|
|
|
1162
1168
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
1163
1169
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
1164
1170
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
1165
|
-
return (h(Host, Object.assign({ key: '
|
|
1171
|
+
return (h(Host, Object.assign({ key: 'bad33199a939bd1e289b3b3f936c676ba403224f', "no-router": true,
|
|
1166
1172
|
// Allow the modal to be navigable when the handle is focusable
|
|
1167
1173
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
1168
1174
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
1169
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '
|
|
1175
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: 'd098688a65fb2d1befb255f0e59fd4c00b401092', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '96cd2e59a7d1c0de7c9afb8f8d366367b09fbc93', class: "modal-shadow" }), h("div", Object.assign({ key: '882ccc39ce344a2c51d6508c11c3f40b26eaf2a7',
|
|
1170
1176
|
/*
|
|
1171
1177
|
role and aria-modal must be used on the
|
|
1172
1178
|
same element. They must also be set inside the
|
|
1173
1179
|
shadow DOM otherwise ion-button will not be highlighted
|
|
1174
1180
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
1181
|
+
|
|
1182
|
+
tabIndex={-1} is required so present() can move focus to this
|
|
1183
|
+
element (which carries the dialog role) instead of the role-less
|
|
1184
|
+
host. role="dialog" alone does not make an element focusable, so
|
|
1185
|
+
without the tabindex focus() would be a no-op and screen readers
|
|
1186
|
+
may not properly announce the dialog and its content when it opens.
|
|
1175
1187
|
*/
|
|
1176
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
1188
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '714d9904fcc8105b21e2bb66cdc032bffd685d72', class: "modal-handle",
|
|
1177
1189
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
1178
|
-
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) })), h("slot", { key: '
|
|
1190
|
+
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) })), h("slot", { key: '79dfbeb3fe5eee7dc3a243ad880d3f63184f3ab7', onSlotchange: this.onSlotChange }))));
|
|
1179
1191
|
}
|
|
1180
1192
|
static get is() { return "ion-modal"; }
|
|
1181
1193
|
static get encapsulation() { return "shadow"; }
|
|
@@ -126,6 +126,14 @@ ion-backdrop {
|
|
|
126
126
|
z-index: 10;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* The wrapper receives programmatic focus for screen readers but should not
|
|
131
|
+
* show a visible focus ring, which is meant only for keyboard navigation.
|
|
132
|
+
*/
|
|
133
|
+
.modal-wrapper {
|
|
134
|
+
outline: none;
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
.modal-shadow {
|
|
130
138
|
position: absolute;
|
|
131
139
|
background: transparent;
|
|
@@ -130,6 +130,17 @@ input {
|
|
|
130
130
|
width: auto;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
:host(.ion-focused) .radio-icon::after {
|
|
134
|
+
border-radius: var(--inner-border-radius);
|
|
135
|
+
display: block;
|
|
136
|
+
position: absolute;
|
|
137
|
+
width: 36px;
|
|
138
|
+
height: 36px;
|
|
139
|
+
background: var(--ion-color-primary-tint, #1a65eb);
|
|
140
|
+
content: "";
|
|
141
|
+
opacity: 0.2;
|
|
142
|
+
}
|
|
143
|
+
|
|
133
144
|
.radio-wrapper {
|
|
134
145
|
display: flex;
|
|
135
146
|
position: relative;
|
|
@@ -456,21 +467,6 @@ input {
|
|
|
456
467
|
opacity: 0.3;
|
|
457
468
|
}
|
|
458
469
|
|
|
459
|
-
:host(.ion-focused) .radio-icon::after {
|
|
460
|
-
border-radius: var(--inner-border-radius);
|
|
461
|
-
top: -8px;
|
|
462
|
-
display: block;
|
|
463
|
-
position: absolute;
|
|
464
|
-
width: 36px;
|
|
465
|
-
height: 36px;
|
|
466
|
-
background: var(--ion-color-primary-tint, #1a65eb);
|
|
467
|
-
content: "";
|
|
468
|
-
opacity: 0.2;
|
|
469
|
-
}
|
|
470
|
-
:host(.ion-focused) .radio-icon::after {
|
|
471
|
-
inset-inline-start: -9px;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
470
|
.native-wrapper .radio-icon {
|
|
475
471
|
width: 0.9375rem;
|
|
476
472
|
height: 1.5rem;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { Host, h } from "@stencil/core";
|
|
5
|
-
import { isOptionSelected } from "../../utils/forms/index";
|
|
4
|
+
import { Host, forceUpdate, h } from "@stencil/core";
|
|
5
|
+
import { createItemMultipleInputsObserver, isOptionSelected } from "../../utils/forms/index";
|
|
6
6
|
import { addEventListener, removeEventListener } from "../../utils/helpers";
|
|
7
7
|
import { createColorClasses, hostContext } from "../../utils/theme";
|
|
8
8
|
import { getIonMode } from "../../global/ionic-global";
|
|
@@ -118,6 +118,7 @@ export class Radio {
|
|
|
118
118
|
this.updateState();
|
|
119
119
|
addEventListener(radioGroup, 'ionValueChange', this.updateState);
|
|
120
120
|
}
|
|
121
|
+
this.itemFocusObserver = createItemMultipleInputsObserver(this.el, () => forceUpdate(this));
|
|
121
122
|
}
|
|
122
123
|
disconnectedCallback() {
|
|
123
124
|
const radioGroup = this.radioGroup;
|
|
@@ -125,6 +126,10 @@ export class Radio {
|
|
|
125
126
|
removeEventListener(radioGroup, 'ionValueChange', this.updateState);
|
|
126
127
|
this.radioGroup = null;
|
|
127
128
|
}
|
|
129
|
+
if (this.itemFocusObserver) {
|
|
130
|
+
this.itemFocusObserver.disconnect();
|
|
131
|
+
this.itemFocusObserver = undefined;
|
|
132
|
+
}
|
|
128
133
|
}
|
|
129
134
|
get hasLabel() {
|
|
130
135
|
return this.el.textContent !== '';
|
|
@@ -136,7 +141,8 @@ export class Radio {
|
|
|
136
141
|
const { checked, disabled, color, el, justify, labelPlacement, hasLabel, buttonTabindex, alignment } = this;
|
|
137
142
|
const mode = getIonMode(this);
|
|
138
143
|
const inItem = hostContext('ion-item', el);
|
|
139
|
-
|
|
144
|
+
const inMultipleInputsItem = hostContext('ion-item.item-multiple-inputs', el);
|
|
145
|
+
return (h(Host, { key: '8622be22eb4f0bab791b479c813c490e21fd9ad8', onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses(color, {
|
|
140
146
|
[mode]: true,
|
|
141
147
|
'in-item': inItem,
|
|
142
148
|
'radio-checked': checked,
|
|
@@ -144,13 +150,15 @@ export class Radio {
|
|
|
144
150
|
[`radio-justify-${justify}`]: justify !== undefined,
|
|
145
151
|
[`radio-alignment-${alignment}`]: alignment !== undefined,
|
|
146
152
|
[`radio-label-placement-${labelPlacement}`]: true,
|
|
147
|
-
//
|
|
153
|
+
// A single-input item has the input cover and draws the indicator itself.
|
|
154
|
+
// A multi-input item has no cover, so each control draws its own. Active
|
|
155
|
+
// styling stays suppressed either way.
|
|
148
156
|
'ion-activatable': !inItem,
|
|
149
|
-
'ion-focusable': !inItem,
|
|
150
|
-
}), role: "radio", "aria-checked": checked ? 'true' : 'false', "aria-disabled": disabled ? 'true' : null, tabindex: buttonTabindex }, h("label", { key: '
|
|
157
|
+
'ion-focusable': !inItem || inMultipleInputsItem,
|
|
158
|
+
}), role: "radio", "aria-checked": checked ? 'true' : 'false', "aria-disabled": disabled ? 'true' : null, tabindex: buttonTabindex }, h("label", { key: 'fb358e14faf37142ccad169adb729f3129371406', class: "radio-wrapper" }, h("div", { key: '844ab615aadf6eef46368ad060afaca9c4222cc1', class: {
|
|
151
159
|
'label-text-wrapper': true,
|
|
152
160
|
'label-text-wrapper-hidden': !hasLabel,
|
|
153
|
-
}, part: "label" }, h("slot", { key: '
|
|
161
|
+
}, part: "label" }, h("slot", { key: 'a57e53d65afda0f2082071c911343a0eb02a00a6' })), h("div", { key: '206ff11e9c2c1946a389f96a3e642335e9c3add6', class: "native-wrapper" }, this.renderRadioControl()))));
|
|
154
162
|
}
|
|
155
163
|
static get is() { return "ion-radio"; }
|
|
156
164
|
static get encapsulation() { return "shadow"; }
|
|
@@ -130,6 +130,17 @@ input {
|
|
|
130
130
|
width: auto;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
:host(.ion-focused) .radio-icon::after {
|
|
134
|
+
border-radius: var(--inner-border-radius);
|
|
135
|
+
display: block;
|
|
136
|
+
position: absolute;
|
|
137
|
+
width: 36px;
|
|
138
|
+
height: 36px;
|
|
139
|
+
background: var(--ion-color-primary-tint, #1a65eb);
|
|
140
|
+
content: "";
|
|
141
|
+
opacity: 0.2;
|
|
142
|
+
}
|
|
143
|
+
|
|
133
144
|
.radio-wrapper {
|
|
134
145
|
display: flex;
|
|
135
146
|
position: relative;
|
|
@@ -477,17 +488,6 @@ input {
|
|
|
477
488
|
opacity: 0.63;
|
|
478
489
|
}
|
|
479
490
|
|
|
480
|
-
:host(.ion-focused) .radio-icon::after {
|
|
481
|
-
border-radius: var(--inner-border-radius);
|
|
482
|
-
display: block;
|
|
483
|
-
position: absolute;
|
|
484
|
-
width: 36px;
|
|
485
|
-
height: 36px;
|
|
486
|
-
background: var(--ion-color-primary-tint, #1a65eb);
|
|
487
|
-
content: "";
|
|
488
|
-
opacity: 0.2;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
491
|
.native-wrapper .radio-icon {
|
|
492
492
|
width: 1.25rem;
|
|
493
493
|
height: 1.25rem;
|
|
@@ -203,7 +203,16 @@ export class Refresher {
|
|
|
203
203
|
});
|
|
204
204
|
};
|
|
205
205
|
this.scrollEl.addEventListener('scroll', this.scrollListenerCallback);
|
|
206
|
-
|
|
206
|
+
const { createGesture } = await import('../../utils/gesture');
|
|
207
|
+
/**
|
|
208
|
+
* Awaiting the dynamic import yields to the event loop, so the component can
|
|
209
|
+
* disconnect before it resolves. disconnectedCallback clears scrollEl, so a
|
|
210
|
+
* missing scrollEl here means there is nothing left to attach a gesture to.
|
|
211
|
+
*/
|
|
212
|
+
if (!this.scrollEl) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.gesture = createGesture({
|
|
207
216
|
el: this.scrollEl,
|
|
208
217
|
gestureName: 'refresher',
|
|
209
218
|
gesturePriority: 31,
|
|
@@ -263,7 +272,16 @@ export class Refresher {
|
|
|
263
272
|
refreshingCircle.style.setProperty('animation-delay', '-655ms');
|
|
264
273
|
});
|
|
265
274
|
}
|
|
266
|
-
|
|
275
|
+
const { createGesture } = await import('../../utils/gesture');
|
|
276
|
+
/**
|
|
277
|
+
* Awaiting the dynamic import yields to the event loop, so the component can
|
|
278
|
+
* disconnect before it resolves. disconnectedCallback clears scrollEl, so a
|
|
279
|
+
* missing scrollEl here means there is nothing left to attach a gesture to.
|
|
280
|
+
*/
|
|
281
|
+
if (!this.scrollEl) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
this.gesture = createGesture({
|
|
267
285
|
el: this.scrollEl,
|
|
268
286
|
gestureName: 'refresher',
|
|
269
287
|
gesturePriority: 31,
|
|
@@ -397,7 +415,16 @@ export class Refresher {
|
|
|
397
415
|
this.setupNativeRefresher(contentEl);
|
|
398
416
|
}
|
|
399
417
|
else {
|
|
400
|
-
|
|
418
|
+
const { createGesture } = await import('../../utils/gesture');
|
|
419
|
+
/**
|
|
420
|
+
* Awaiting the dynamic import yields to the event loop, so the component can
|
|
421
|
+
* disconnect before it resolves. A disconnected contentEl means there is
|
|
422
|
+
* nothing left to attach a gesture to.
|
|
423
|
+
*/
|
|
424
|
+
if (!contentEl.isConnected) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
this.gesture = createGesture({
|
|
401
428
|
el: contentEl,
|
|
402
429
|
gestureName: 'refresher',
|
|
403
430
|
gesturePriority: 31,
|
|
@@ -716,7 +743,7 @@ export class Refresher {
|
|
|
716
743
|
}
|
|
717
744
|
render() {
|
|
718
745
|
const mode = getIonMode(this);
|
|
719
|
-
return (h(Host, { key: '
|
|
746
|
+
return (h(Host, { key: '2eaca7f85b3d40418f213077434e519dfacd9d42', slot: "fixed", class: {
|
|
720
747
|
[mode]: true,
|
|
721
748
|
// Used internally for styling
|
|
722
749
|
[`refresher-${mode}`]: true,
|
|
@@ -243,12 +243,14 @@ export class Searchbar {
|
|
|
243
243
|
}, 300);
|
|
244
244
|
}
|
|
245
245
|
disconnectedCallback() {
|
|
246
|
+
var _a;
|
|
246
247
|
if (this.loadTimeout) {
|
|
247
248
|
clearTimeout(this.loadTimeout);
|
|
248
249
|
}
|
|
249
250
|
if (this.clearTimeout) {
|
|
250
251
|
clearTimeout(this.clearTimeout);
|
|
251
252
|
}
|
|
253
|
+
(_a = this.searchIconResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
252
254
|
}
|
|
253
255
|
emitStyle() {
|
|
254
256
|
this.ionStyle.emit({
|
|
@@ -346,6 +348,7 @@ export class Searchbar {
|
|
|
346
348
|
doc.body.appendChild(tempSpan);
|
|
347
349
|
// Get the width of the span then remove it
|
|
348
350
|
raf(() => {
|
|
351
|
+
var _a, _b;
|
|
349
352
|
const textWidth = tempSpan.offsetWidth;
|
|
350
353
|
tempSpan.remove();
|
|
351
354
|
// Calculate the input padding
|
|
@@ -357,7 +360,25 @@ export class Searchbar {
|
|
|
357
360
|
* such as Dynamic Type on iOS as well as 8px
|
|
358
361
|
* of padding.
|
|
359
362
|
*/
|
|
360
|
-
const
|
|
363
|
+
const iconWidth = iconEl.clientWidth;
|
|
364
|
+
/**
|
|
365
|
+
* Fix for https://github.com/ionic-team/ionic-framework/issues/30434:
|
|
366
|
+
* iconEl.clientWidth can very briefly be 0 when this is called from componentDidLoad.
|
|
367
|
+
* If it is zero, set up a ResizeObserver and call this function when it observes a width greater than 0.
|
|
368
|
+
*/
|
|
369
|
+
if (iconWidth === 0) {
|
|
370
|
+
(_a = this.searchIconResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
371
|
+
this.searchIconResizeObserver = new ResizeObserver((entries) => {
|
|
372
|
+
var _a;
|
|
373
|
+
if (entries[0].contentRect.width > 0) {
|
|
374
|
+
(_a = this.searchIconResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
375
|
+
this.positionPlaceholder();
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
(_b = this.searchIconResizeObserver) === null || _b === void 0 ? void 0 : _b.observe(iconEl);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const iconLeft = 'calc(50% - ' + (textWidth / 2 + iconWidth + 8) + 'px)';
|
|
361
382
|
// Set the input padding start and icon margin start
|
|
362
383
|
if (rtl) {
|
|
363
384
|
inputEl.style.paddingRight = inputLeft;
|
|
@@ -438,8 +459,8 @@ export class Searchbar {
|
|
|
438
459
|
const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
|
|
439
460
|
const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
|
|
440
461
|
const shouldShowCancelButton = this.shouldShowCancelButton();
|
|
441
|
-
const cancelButton = this.showCancelButton !== 'never' && (h("button", { key: '
|
|
442
|
-
return (h(Host, { key: '
|
|
462
|
+
const cancelButton = this.showCancelButton !== 'never' && (h("button", { key: '226b7a676b4819cda4062b8334fa8d4c4cee6f1a', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, h("div", { key: '89adb4efa17a78c973bbd5527cfac91d99ceb9bb', "aria-hidden": "true" }, mode === 'md' ? (h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
|
|
463
|
+
return (h(Host, { key: '237dd767403dba3cb3d7de8905996e275669da3b', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
|
|
443
464
|
[mode]: true,
|
|
444
465
|
'searchbar-animated': animated,
|
|
445
466
|
'searchbar-disabled': this.disabled,
|
|
@@ -449,14 +470,14 @@ export class Searchbar {
|
|
|
449
470
|
'searchbar-has-focus': this.focused,
|
|
450
471
|
'searchbar-should-show-clear': this.shouldShowClearButton(),
|
|
451
472
|
'searchbar-should-show-cancel': this.shouldShowCancelButton(),
|
|
452
|
-
}) }, h("div", { key: '
|
|
473
|
+
}) }, h("div", { key: '5b4bdf7280bea710304b6975e76390fe6ceb7417', class: "searchbar-input-container" }, h("input", Object.assign({ key: '01a0820a2cf904aec1c7d84b542ab7918d435632', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, h("ion-icon", { key: 'cd64973206b1cc59d221112861733b7ee25f0323', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), h("button", { key: '2061fa8449bbc576cf8c5130ea613378ea492944', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
|
|
453
474
|
/**
|
|
454
475
|
* This prevents mobile browsers from
|
|
455
476
|
* blurring the input when the clear
|
|
456
477
|
* button is activated.
|
|
457
478
|
*/
|
|
458
479
|
ev.preventDefault();
|
|
459
|
-
}, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '
|
|
480
|
+
}, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '00df6f7742bff70b1b088d544b8c00e962e7216c', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
|
|
460
481
|
}
|
|
461
482
|
static get is() { return "ion-searchbar"; }
|
|
462
483
|
static get encapsulation() { return "scoped"; }
|
|
@@ -836,8 +836,9 @@ export class Select {
|
|
|
836
836
|
*
|
|
837
837
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
838
838
|
*/
|
|
839
|
-
const labelShouldFloat = labelPlacement === 'stacked' ||
|
|
840
|
-
|
|
839
|
+
const labelShouldFloat = labelPlacement === 'stacked' ||
|
|
840
|
+
(labelPlacement === 'floating' && (hasValue || hasFocus || isExpanded || hasStartEndSlots));
|
|
841
|
+
return (h(Host, { key: 'f16327d6866ffee76e1618fcd3281590ca0fd56d', onClick: this.onClick, class: createColorClasses(this.color, {
|
|
841
842
|
[mode]: true,
|
|
842
843
|
'in-item': inItem,
|
|
843
844
|
'in-item-color': hostContext('ion-item.ion-color', el),
|
|
@@ -855,7 +856,7 @@ export class Select {
|
|
|
855
856
|
[`select-justify-${justify}`]: justifyEnabled,
|
|
856
857
|
[`select-shape-${shape}`]: shape !== undefined,
|
|
857
858
|
[`select-label-placement-${labelPlacement}`]: true,
|
|
858
|
-
}) }, h("label", { key: '
|
|
859
|
+
}) }, h("label", { key: 'db13f76b384a7a7461c1ad752108eadf9c0213be', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: '2fb0e57bd596c0f525be79293b7da4aca55a9385', class: "select-wrapper-inner", part: "inner" }, h("slot", { key: 'cd694c36242789a89461ed3412af9891ad68411b', name: "start" }), h("div", { key: 'fdf62911be54f4ab29eb3c2eb153f082e76a8f49', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: 'a32f5c4b101d4d6ad45870f4c4446960009377f5', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '61f792024a5f221ef4f28a3c249bd3a0de5edeab', class: "select-highlight" })), this.renderBottomContent()));
|
|
859
860
|
}
|
|
860
861
|
static get is() { return "ion-select"; }
|
|
861
862
|
static get encapsulation() { return "shadow"; }
|