@ionic/core 8.7.17-nightly.20260114 → 8.7.18-dev.11768592717.14a59d2f

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.
Files changed (32) hide show
  1. package/components/ion-footer.js +23 -3
  2. package/components/ion-input.js +35 -6
  3. package/components/ion-tab-bar.js +23 -3
  4. package/components/ion-toast.js +2 -2
  5. package/dist/cjs/ion-app_8.cjs.entry.js +23 -3
  6. package/dist/cjs/ion-input.cjs.entry.js +35 -6
  7. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +23 -3
  8. package/dist/cjs/ion-toast.cjs.entry.js +2 -2
  9. package/dist/collection/components/footer/footer.js +23 -3
  10. package/dist/collection/components/input/input.js +35 -6
  11. package/dist/collection/components/tab-bar/tab-bar.js +23 -3
  12. package/dist/collection/components/toast/toast.ios.css +1 -1
  13. package/dist/collection/components/toast/toast.md.css +1 -1
  14. package/dist/docs.json +1 -1
  15. package/dist/esm/ion-app_8.entry.js +23 -3
  16. package/dist/esm/ion-input.entry.js +35 -6
  17. package/dist/esm/ion-tab-bar_2.entry.js +23 -3
  18. package/dist/esm/ion-toast.entry.js +2 -2
  19. package/dist/ionic/ionic.esm.js +1 -1
  20. package/dist/ionic/{p-b3d44509.entry.js → p-0e8c8a10.entry.js} +1 -1
  21. package/dist/ionic/p-172a579f.entry.js +4 -0
  22. package/dist/ionic/p-1ccd6829.entry.js +4 -0
  23. package/dist/ionic/p-66fbe052.entry.js +4 -0
  24. package/dist/types/components/footer/footer.d.ts +1 -0
  25. package/dist/types/components/input/input.d.ts +11 -0
  26. package/dist/types/components/tab-bar/tab-bar.d.ts +1 -0
  27. package/hydrate/index.js +82 -14
  28. package/hydrate/index.mjs +82 -14
  29. package/package.json +1 -1
  30. package/dist/ionic/p-7268efa5.entry.js +0 -4
  31. package/dist/ionic/p-9ab2d871.entry.js +0 -4
  32. package/dist/ionic/p-db8027bd.entry.js +0 -4
@@ -47,6 +47,7 @@ const Footer = /*@__PURE__*/ proxyCustomElement(class Footer extends HTMLElement
47
47
  this.__registerHost();
48
48
  }
49
49
  this.keyboardCtrl = null;
50
+ this.keyboardCtrlPromise = null;
50
51
  this.keyboardVisible = false;
51
52
  /**
52
53
  * If `true`, the footer will be translucent.
@@ -94,7 +95,7 @@ const Footer = /*@__PURE__*/ proxyCustomElement(class Footer extends HTMLElement
94
95
  this.checkCollapsibleFooter();
95
96
  }
96
97
  async connectedCallback() {
97
- this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
98
+ const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
98
99
  /**
99
100
  * If the keyboard is hiding, then we need to wait
100
101
  * for the webview to resize. Otherwise, the footer
@@ -105,10 +106,29 @@ const Footer = /*@__PURE__*/ proxyCustomElement(class Footer extends HTMLElement
105
106
  }
106
107
  this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
107
108
  });
109
+ this.keyboardCtrlPromise = promise;
110
+ const keyboardCtrl = await promise;
111
+ /**
112
+ * Only assign if this is still the current promise.
113
+ * Otherwise, a new connectedCallback has started or
114
+ * disconnectedCallback was called, so destroy this instance.
115
+ */
116
+ if (this.keyboardCtrlPromise === promise) {
117
+ this.keyboardCtrl = keyboardCtrl;
118
+ this.keyboardCtrlPromise = null;
119
+ }
120
+ else {
121
+ keyboardCtrl.destroy();
122
+ }
108
123
  }
109
124
  disconnectedCallback() {
125
+ if (this.keyboardCtrlPromise) {
126
+ this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
127
+ this.keyboardCtrlPromise = null;
128
+ }
110
129
  if (this.keyboardCtrl) {
111
130
  this.keyboardCtrl.destroy();
131
+ this.keyboardCtrl = null;
112
132
  }
113
133
  }
114
134
  destroyCollapsibleFooter() {
@@ -122,7 +142,7 @@ const Footer = /*@__PURE__*/ proxyCustomElement(class Footer extends HTMLElement
122
142
  const mode = getIonMode(this);
123
143
  const tabs = this.el.closest('ion-tabs');
124
144
  const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
125
- return (h(Host, { key: 'ddc228f1a1e7fa4f707dccf74db2490ca3241137', role: "contentinfo", class: {
145
+ return (h(Host, { key: '71939c4bbaef5062532a99ee2e33574102a9abad', role: "contentinfo", class: {
126
146
  [mode]: true,
127
147
  // Used internally for styling
128
148
  [`footer-${mode}`]: true,
@@ -130,7 +150,7 @@ const Footer = /*@__PURE__*/ proxyCustomElement(class Footer extends HTMLElement
130
150
  [`footer-translucent-${mode}`]: translucent,
131
151
  ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
132
152
  [`footer-collapse-${collapse}`]: collapse !== undefined,
133
- } }, mode === 'ios' && translucent && h("div", { key: 'e16ed4963ff94e06de77eb8038201820af73937c', class: "footer-background" }), h("slot", { key: 'f186934febf85d37133d9351a96c1a64b0a4b203' })));
153
+ } }, mode === 'ios' && translucent && h("div", { key: '2fa14f61661c47c661cecd696176728d6eafa74f', class: "footer-background" }), h("slot", { key: '8e63696e7c528d5c38201e546bf08135290d0945' })));
134
154
  }
135
155
  get el() { return this; }
136
156
  static get style() { return {
@@ -28,6 +28,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
28
28
  this.inputId = `ion-input-${inputIds++}`;
29
29
  this.helperTextId = `${this.inputId}-helper-text`;
30
30
  this.errorTextId = `${this.inputId}-error-text`;
31
+ this.labelTextId = `${this.inputId}-label`;
31
32
  this.inheritedAttributes = {};
32
33
  this.isComposing = false;
33
34
  /**
@@ -236,7 +237,11 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
236
237
  }
237
238
  connectedCallback() {
238
239
  const { el } = this;
239
- this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
240
+ this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => {
241
+ this.setSlottedLabelId();
242
+ forceUpdate(this);
243
+ });
244
+ this.setSlottedLabelId();
240
245
  this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
241
246
  // Watch for class changes to update validation state
242
247
  if (Build.isBrowser && typeof MutationObserver !== 'undefined') {
@@ -439,11 +444,11 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
439
444
  return (h("div", { class: "input-bottom" }, this.renderHintText(), this.renderCounter()));
440
445
  }
441
446
  renderLabel() {
442
- const { label } = this;
447
+ const { label, labelTextId } = this;
443
448
  return (h("div", { class: {
444
449
  'label-text-wrapper': true,
445
450
  'label-text-wrapper-hidden': !this.hasLabel,
446
- } }, label === undefined ? h("slot", { name: "label" }) : h("div", { class: "label-text" }, label)));
451
+ }, "aria-hidden": this.hasLabel ? 'true' : null }, label === undefined ? (h("slot", { name: "label" })) : (h("div", { class: "label-text", id: labelTextId }, label))));
447
452
  }
448
453
  /**
449
454
  * Gets any content passed into the `label` slot,
@@ -452,6 +457,30 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
452
457
  get labelSlot() {
453
458
  return this.el.querySelector('[slot="label"]');
454
459
  }
460
+ /**
461
+ * Ensures the slotted label element has an ID for aria-labelledby.
462
+ * If no ID exists, we assign one using our generated labelTextId.
463
+ */
464
+ setSlottedLabelId() {
465
+ const slottedLabel = this.labelSlot;
466
+ if (slottedLabel && !slottedLabel.id) {
467
+ slottedLabel.id = this.labelTextId;
468
+ }
469
+ }
470
+ /**
471
+ * Returns the ID to use for aria-labelledby on the native input,
472
+ * or undefined if aria-label is explicitly set (to avoid conflicts).
473
+ */
474
+ getLabelledById() {
475
+ var _a;
476
+ if (this.inheritedAttributes['aria-label']) {
477
+ return undefined;
478
+ }
479
+ if (this.label !== undefined) {
480
+ return this.labelTextId;
481
+ }
482
+ return ((_a = this.labelSlot) === null || _a === void 0 ? void 0 : _a.id) || undefined;
483
+ }
455
484
  /**
456
485
  * Returns `true` if label content is provided
457
486
  * either by a prop or a content. If you want
@@ -518,7 +547,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
518
547
  * TODO(FW-5592): Remove hasStartEndSlots condition
519
548
  */
520
549
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
521
- return (h(Host, { key: '97b5308021064d9e7434ef2d3d96f27045c1b0c4', class: createColorClasses(this.color, {
550
+ return (h(Host, { key: '9ba9cf425b573d2ca9ac34455a0e6b8474c4de6d', class: createColorClasses(this.color, {
522
551
  [mode]: true,
523
552
  'has-value': hasValue,
524
553
  'has-focus': hasFocus,
@@ -529,14 +558,14 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
529
558
  'in-item': inItem,
530
559
  'in-item-color': hostContext('ion-item.ion-color', this.el),
531
560
  'input-disabled': disabled,
532
- }) }, h("label", { key: '353f68726ce180299bd9adc81e5ff7d26a48f54f', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '2034b4bad04fc157f3298a1805819216b6f439d0', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '96bb5e30176b2bd76dfb75bfbf6c1c3d4403f4bb', name: "start" }), h("input", Object.assign({ key: '1a1d75b0e414a95c89d5a760757c33548d234aca', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: '95f3df17b7691d9a2e7dcd4a51f16a94aa3ca36f', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
561
+ }) }, h("label", { key: '74b989d0aa5ab38f29f952519868f05119df6005', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '47f2b42e2f74ea866b4f871026e08ab375d7a726', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: 'eaabe5a4a329a356cac3294d15c087d0d131fff2', name: "start" }), h("input", Object.assign({ key: 'c821a984a8a9b7f96f30892c06d8deda093ff24b', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.getLabelledById() }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: '62069c11016ee190dc46ab941372e1c4ad8a36ed', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
533
562
  /**
534
563
  * This prevents mobile browsers from
535
564
  * blurring the input when the clear
536
565
  * button is activated.
537
566
  */
538
567
  ev.preventDefault();
539
- }, onClick: this.clearTextInput }, h("ion-icon", { key: '16b0af75eed50c8115fb5597f73b5fbf71c2530e', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: 'c48da0f8ddb3764ac43efa705bb4a6bb2d9cc2fd', name: "end" })), shouldRenderHighlight && h("div", { key: 'f15238481fc20de56ca7ecb6e350b3c024cc755e', class: "input-highlight" })), this.renderBottomContent()));
568
+ }, onClick: this.clearTextInput }, h("ion-icon", { key: 'dd75a516d32110d85382b664c663bd41f177ce12', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '330d4b9389f2c62223a5ee24003e96ef3e6b2473', name: "end" })), shouldRenderHighlight && h("div", { key: '8e442bed130ddc84976ab70fd3f8578d6bcc6316', class: "input-highlight" })), this.renderBottomContent()));
540
569
  }
541
570
  get el() { return this; }
542
571
  static get watchers() { return {
@@ -20,6 +20,7 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
20
20
  this.ionTabBarChanged = createEvent(this, "ionTabBarChanged", 7);
21
21
  this.ionTabBarLoaded = createEvent(this, "ionTabBarLoaded", 7);
22
22
  this.keyboardCtrl = null;
23
+ this.keyboardCtrlPromise = null;
23
24
  this.didLoad = false;
24
25
  this.keyboardVisible = false;
25
26
  /**
@@ -55,7 +56,7 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
55
56
  }
56
57
  }
57
58
  async connectedCallback() {
58
- this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
59
+ const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
59
60
  /**
60
61
  * If the keyboard is hiding, then we need to wait
61
62
  * for the webview to resize. Otherwise, the tab bar
@@ -66,21 +67,40 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
66
67
  }
67
68
  this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
68
69
  });
70
+ this.keyboardCtrlPromise = promise;
71
+ const keyboardCtrl = await promise;
72
+ /**
73
+ * Only assign if this is still the current promise.
74
+ * Otherwise, a new connectedCallback has started or
75
+ * disconnectedCallback was called, so destroy this instance.
76
+ */
77
+ if (this.keyboardCtrlPromise === promise) {
78
+ this.keyboardCtrl = keyboardCtrl;
79
+ this.keyboardCtrlPromise = null;
80
+ }
81
+ else {
82
+ keyboardCtrl.destroy();
83
+ }
69
84
  }
70
85
  disconnectedCallback() {
86
+ if (this.keyboardCtrlPromise) {
87
+ this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
88
+ this.keyboardCtrlPromise = null;
89
+ }
71
90
  if (this.keyboardCtrl) {
72
91
  this.keyboardCtrl.destroy();
92
+ this.keyboardCtrl = null;
73
93
  }
74
94
  }
75
95
  render() {
76
96
  const { color, translucent, keyboardVisible } = this;
77
97
  const mode = getIonMode(this);
78
98
  const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
79
- return (h(Host, { key: '388ec37ce308035bab78d6c9a016bb616e9517a9', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses(color, {
99
+ return (h(Host, { key: '9daf4e2acaff6e3ce3878cf9dd5109fb1afbbebe', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses(color, {
80
100
  [mode]: true,
81
101
  'tab-bar-translucent': translucent,
82
102
  'tab-bar-hidden': shouldHide,
83
- }) }, h("slot", { key: 'ce10ade2b86725e24f3254516483eeedd8ecb16a' })));
103
+ }) }, h("slot", { key: '1d15aa2da8501e8e7eff11ad4a491478be845c43' })));
84
104
  }
85
105
  get el() { return this; }
86
106
  static get watchers() { return {
@@ -451,9 +451,9 @@ const createSwipeToDismissGesture = (el, toastPosition, onDismiss) => {
451
451
  return gesture;
452
452
  };
453
453
 
454
- const toastIosCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-radius:14px;--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--max-width:700px;--max-height:478px;--start:10px;--end:10px;font-size:clamp(14px, 0.875rem, 43.4px)}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;z-index:10}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.toast-translucent) .toast-wrapper{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}:host(.ion-color.toast-translucent) .toast-wrapper{background:rgba(var(--ion-color-base-rgb), 0.8)}}.toast-wrapper.toast-middle{opacity:0.01}.toast-content{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:15px;padding-bottom:15px}.toast-header{margin-bottom:2px;font-weight:500}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;min-height:44px;-webkit-transition:background-color, opacity 100ms linear;transition:background-color, opacity 100ms linear;border:0;background-color:transparent;font-family:var(--ion-font-family);font-size:clamp(17px, 1.0625rem, 21.998px);font-weight:500;overflow:hidden}.toast-button.ion-activated{opacity:0.4}@media (any-hover: hover){.toast-button:hover{opacity:0.6}}";
454
+ const toastIosCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{-ms-flex:1;flex:1;min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-radius:14px;--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--max-width:700px;--max-height:478px;--start:10px;--end:10px;font-size:clamp(14px, 0.875rem, 43.4px)}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;z-index:10}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.toast-translucent) .toast-wrapper{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}:host(.ion-color.toast-translucent) .toast-wrapper{background:rgba(var(--ion-color-base-rgb), 0.8)}}.toast-wrapper.toast-middle{opacity:0.01}.toast-content{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:15px;padding-bottom:15px}.toast-header{margin-bottom:2px;font-weight:500}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;min-height:44px;-webkit-transition:background-color, opacity 100ms linear;transition:background-color, opacity 100ms linear;border:0;background-color:transparent;font-family:var(--ion-font-family);font-size:clamp(17px, 1.0625rem, 21.998px);font-weight:500;overflow:hidden}.toast-button.ion-activated{opacity:0.4}@media (any-hover: hover){.toast-button:hover{opacity:0.6}}";
455
455
 
456
- const toastMdCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-800, var(--ion-background-color-step-800, #333333));--border-radius:4px;--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-50, var(--ion-text-color-step-950, #f2f2f2));--max-width:700px;--start:8px;--end:8px;font-size:0.875rem}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;opacity:0.01;z-index:10}.toast-content{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:14px;padding-bottom:14px}.toast-header{margin-bottom:2px;font-weight:500;line-height:1.25rem}.toast-message{line-height:1.25rem}.toast-layout-baseline .toast-button-group-start{-webkit-margin-start:8px;margin-inline-start:8px}.toast-layout-stacked .toast-button-group-start{-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px}.toast-layout-baseline .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px}.toast-layout-stacked .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px;margin-bottom:8px}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;font-family:var(--ion-font-family);font-size:0.875rem;font-weight:500;letter-spacing:0.84px;text-transform:uppercase;overflow:hidden}.toast-button-cancel{color:var(--ion-color-step-100, var(--ion-text-color-step-900, #e6e6e6))}.toast-button-icon-only{border-radius:50%;-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:9px;padding-bottom:9px;width:36px;height:36px}@media (any-hover: hover){.toast-button:hover{background-color:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08)}.toast-button-cancel:hover{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.08)}}";
456
+ const toastMdCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{-ms-flex:1;flex:1;min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-800, var(--ion-background-color-step-800, #333333));--border-radius:4px;--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-50, var(--ion-text-color-step-950, #f2f2f2));--max-width:700px;--start:8px;--end:8px;font-size:0.875rem}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;opacity:0.01;z-index:10}.toast-content{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:14px;padding-bottom:14px}.toast-header{margin-bottom:2px;font-weight:500;line-height:1.25rem}.toast-message{line-height:1.25rem}.toast-layout-baseline .toast-button-group-start{-webkit-margin-start:8px;margin-inline-start:8px}.toast-layout-stacked .toast-button-group-start{-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px}.toast-layout-baseline .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px}.toast-layout-stacked .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px;margin-bottom:8px}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;font-family:var(--ion-font-family);font-size:0.875rem;font-weight:500;letter-spacing:0.84px;text-transform:uppercase;overflow:hidden}.toast-button-cancel{color:var(--ion-color-step-100, var(--ion-text-color-step-900, #e6e6e6))}.toast-button-icon-only{border-radius:50%;-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:9px;padding-bottom:9px;width:36px;height:36px}@media (any-hover: hover){.toast-button:hover{background-color:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08)}.toast-button-cancel:hover{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.08)}}";
457
457
 
458
458
  const Toast = /*@__PURE__*/ proxyCustomElement(class Toast extends HTMLElement {
459
459
  constructor(registerHost) {
@@ -626,6 +626,7 @@ const Footer = class {
626
626
  constructor(hostRef) {
627
627
  index.registerInstance(this, hostRef);
628
628
  this.keyboardCtrl = null;
629
+ this.keyboardCtrlPromise = null;
629
630
  this.keyboardVisible = false;
630
631
  /**
631
632
  * If `true`, the footer will be translucent.
@@ -673,7 +674,7 @@ const Footer = class {
673
674
  this.checkCollapsibleFooter();
674
675
  }
675
676
  async connectedCallback() {
676
- this.keyboardCtrl = await keyboardController.createKeyboardController(async (keyboardOpen, waitForResize) => {
677
+ const promise = keyboardController.createKeyboardController(async (keyboardOpen, waitForResize) => {
677
678
  /**
678
679
  * If the keyboard is hiding, then we need to wait
679
680
  * for the webview to resize. Otherwise, the footer
@@ -684,10 +685,29 @@ const Footer = class {
684
685
  }
685
686
  this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
686
687
  });
688
+ this.keyboardCtrlPromise = promise;
689
+ const keyboardCtrl = await promise;
690
+ /**
691
+ * Only assign if this is still the current promise.
692
+ * Otherwise, a new connectedCallback has started or
693
+ * disconnectedCallback was called, so destroy this instance.
694
+ */
695
+ if (this.keyboardCtrlPromise === promise) {
696
+ this.keyboardCtrl = keyboardCtrl;
697
+ this.keyboardCtrlPromise = null;
698
+ }
699
+ else {
700
+ keyboardCtrl.destroy();
701
+ }
687
702
  }
688
703
  disconnectedCallback() {
704
+ if (this.keyboardCtrlPromise) {
705
+ this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
706
+ this.keyboardCtrlPromise = null;
707
+ }
689
708
  if (this.keyboardCtrl) {
690
709
  this.keyboardCtrl.destroy();
710
+ this.keyboardCtrl = null;
691
711
  }
692
712
  }
693
713
  destroyCollapsibleFooter() {
@@ -701,7 +721,7 @@ const Footer = class {
701
721
  const mode = ionicGlobal.getIonMode(this);
702
722
  const tabs = this.el.closest('ion-tabs');
703
723
  const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
704
- return (index.h(index.Host, { key: 'ddc228f1a1e7fa4f707dccf74db2490ca3241137', role: "contentinfo", class: {
724
+ return (index.h(index.Host, { key: '71939c4bbaef5062532a99ee2e33574102a9abad', role: "contentinfo", class: {
705
725
  [mode]: true,
706
726
  // Used internally for styling
707
727
  [`footer-${mode}`]: true,
@@ -709,7 +729,7 @@ const Footer = class {
709
729
  [`footer-translucent-${mode}`]: translucent,
710
730
  ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
711
731
  [`footer-collapse-${collapse}`]: collapse !== undefined,
712
- } }, mode === 'ios' && translucent && index.h("div", { key: 'e16ed4963ff94e06de77eb8038201820af73937c', class: "footer-background" }), index.h("slot", { key: 'f186934febf85d37133d9351a96c1a64b0a4b203' })));
732
+ } }, mode === 'ios' && translucent && index.h("div", { key: '2fa14f61661c47c661cecd696176728d6eafa74f', class: "footer-background" }), index.h("slot", { key: '8e63696e7c528d5c38201e546bf08135290d0945' })));
713
733
  }
714
734
  get el() { return index.getElement(this); }
715
735
  };
@@ -27,6 +27,7 @@ const Input = class {
27
27
  this.inputId = `ion-input-${inputIds++}`;
28
28
  this.helperTextId = `${this.inputId}-helper-text`;
29
29
  this.errorTextId = `${this.inputId}-error-text`;
30
+ this.labelTextId = `${this.inputId}-label`;
30
31
  this.inheritedAttributes = {};
31
32
  this.isComposing = false;
32
33
  /**
@@ -235,7 +236,11 @@ const Input = class {
235
236
  }
236
237
  connectedCallback() {
237
238
  const { el } = this;
238
- this.slotMutationController = input_utils.createSlotMutationController(el, ['label', 'start', 'end'], () => index.forceUpdate(this));
239
+ this.slotMutationController = input_utils.createSlotMutationController(el, ['label', 'start', 'end'], () => {
240
+ this.setSlottedLabelId();
241
+ index.forceUpdate(this);
242
+ });
243
+ this.setSlottedLabelId();
239
244
  this.notchController = notchController.createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
240
245
  // Watch for class changes to update validation state
241
246
  if (typeof MutationObserver !== 'undefined') {
@@ -438,11 +443,11 @@ const Input = class {
438
443
  return (index.h("div", { class: "input-bottom" }, this.renderHintText(), this.renderCounter()));
439
444
  }
440
445
  renderLabel() {
441
- const { label } = this;
446
+ const { label, labelTextId } = this;
442
447
  return (index.h("div", { class: {
443
448
  'label-text-wrapper': true,
444
449
  'label-text-wrapper-hidden': !this.hasLabel,
445
- } }, label === undefined ? index.h("slot", { name: "label" }) : index.h("div", { class: "label-text" }, label)));
450
+ }, "aria-hidden": this.hasLabel ? 'true' : null }, label === undefined ? (index.h("slot", { name: "label" })) : (index.h("div", { class: "label-text", id: labelTextId }, label))));
446
451
  }
447
452
  /**
448
453
  * Gets any content passed into the `label` slot,
@@ -451,6 +456,30 @@ const Input = class {
451
456
  get labelSlot() {
452
457
  return this.el.querySelector('[slot="label"]');
453
458
  }
459
+ /**
460
+ * Ensures the slotted label element has an ID for aria-labelledby.
461
+ * If no ID exists, we assign one using our generated labelTextId.
462
+ */
463
+ setSlottedLabelId() {
464
+ const slottedLabel = this.labelSlot;
465
+ if (slottedLabel && !slottedLabel.id) {
466
+ slottedLabel.id = this.labelTextId;
467
+ }
468
+ }
469
+ /**
470
+ * Returns the ID to use for aria-labelledby on the native input,
471
+ * or undefined if aria-label is explicitly set (to avoid conflicts).
472
+ */
473
+ getLabelledById() {
474
+ var _a;
475
+ if (this.inheritedAttributes['aria-label']) {
476
+ return undefined;
477
+ }
478
+ if (this.label !== undefined) {
479
+ return this.labelTextId;
480
+ }
481
+ return ((_a = this.labelSlot) === null || _a === void 0 ? void 0 : _a.id) || undefined;
482
+ }
454
483
  /**
455
484
  * Returns `true` if label content is provided
456
485
  * either by a prop or a content. If you want
@@ -517,7 +546,7 @@ const Input = class {
517
546
  * TODO(FW-5592): Remove hasStartEndSlots condition
518
547
  */
519
548
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
520
- return (index.h(index.Host, { key: '97b5308021064d9e7434ef2d3d96f27045c1b0c4', class: theme.createColorClasses(this.color, {
549
+ return (index.h(index.Host, { key: '9ba9cf425b573d2ca9ac34455a0e6b8474c4de6d', class: theme.createColorClasses(this.color, {
521
550
  [mode]: true,
522
551
  'has-value': hasValue,
523
552
  'has-focus': hasFocus,
@@ -528,14 +557,14 @@ const Input = class {
528
557
  'in-item': inItem,
529
558
  'in-item-color': theme.hostContext('ion-item.ion-color', this.el),
530
559
  'input-disabled': disabled,
531
- }) }, index.h("label", { key: '353f68726ce180299bd9adc81e5ff7d26a48f54f', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: '2034b4bad04fc157f3298a1805819216b6f439d0', class: "native-wrapper", onClick: this.onLabelClick }, index.h("slot", { key: '96bb5e30176b2bd76dfb75bfbf6c1c3d4403f4bb', name: "start" }), index.h("input", Object.assign({ key: '1a1d75b0e414a95c89d5a760757c33548d234aca', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (index.h("button", { key: '95f3df17b7691d9a2e7dcd4a51f16a94aa3ca36f', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
560
+ }) }, index.h("label", { key: '74b989d0aa5ab38f29f952519868f05119df6005', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: '47f2b42e2f74ea866b4f871026e08ab375d7a726', class: "native-wrapper", onClick: this.onLabelClick }, index.h("slot", { key: 'eaabe5a4a329a356cac3294d15c087d0d131fff2', name: "start" }), index.h("input", Object.assign({ key: 'c821a984a8a9b7f96f30892c06d8deda093ff24b', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.getLabelledById() }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (index.h("button", { key: '62069c11016ee190dc46ab941372e1c4ad8a36ed', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
532
561
  /**
533
562
  * This prevents mobile browsers from
534
563
  * blurring the input when the clear
535
564
  * button is activated.
536
565
  */
537
566
  ev.preventDefault();
538
- }, onClick: this.clearTextInput }, index.h("ion-icon", { key: '16b0af75eed50c8115fb5597f73b5fbf71c2530e', "aria-hidden": "true", icon: clearIconData }))), index.h("slot", { key: 'c48da0f8ddb3764ac43efa705bb4a6bb2d9cc2fd', name: "end" })), shouldRenderHighlight && index.h("div", { key: 'f15238481fc20de56ca7ecb6e350b3c024cc755e', class: "input-highlight" })), this.renderBottomContent()));
567
+ }, onClick: this.clearTextInput }, index.h("ion-icon", { key: 'dd75a516d32110d85382b664c663bd41f177ce12', "aria-hidden": "true", icon: clearIconData }))), index.h("slot", { key: '330d4b9389f2c62223a5ee24003e96ef3e6b2473', name: "end" })), shouldRenderHighlight && index.h("div", { key: '8e442bed130ddc84976ab70fd3f8578d6bcc6316', class: "input-highlight" })), this.renderBottomContent()));
539
568
  }
540
569
  get el() { return index.getElement(this); }
541
570
  static get watchers() { return {
@@ -22,6 +22,7 @@ const TabBar = class {
22
22
  this.ionTabBarChanged = index.createEvent(this, "ionTabBarChanged", 7);
23
23
  this.ionTabBarLoaded = index.createEvent(this, "ionTabBarLoaded", 7);
24
24
  this.keyboardCtrl = null;
25
+ this.keyboardCtrlPromise = null;
25
26
  this.didLoad = false;
26
27
  this.keyboardVisible = false;
27
28
  /**
@@ -57,7 +58,7 @@ const TabBar = class {
57
58
  }
58
59
  }
59
60
  async connectedCallback() {
60
- this.keyboardCtrl = await keyboardController.createKeyboardController(async (keyboardOpen, waitForResize) => {
61
+ const promise = keyboardController.createKeyboardController(async (keyboardOpen, waitForResize) => {
61
62
  /**
62
63
  * If the keyboard is hiding, then we need to wait
63
64
  * for the webview to resize. Otherwise, the tab bar
@@ -68,21 +69,40 @@ const TabBar = class {
68
69
  }
69
70
  this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
70
71
  });
72
+ this.keyboardCtrlPromise = promise;
73
+ const keyboardCtrl = await promise;
74
+ /**
75
+ * Only assign if this is still the current promise.
76
+ * Otherwise, a new connectedCallback has started or
77
+ * disconnectedCallback was called, so destroy this instance.
78
+ */
79
+ if (this.keyboardCtrlPromise === promise) {
80
+ this.keyboardCtrl = keyboardCtrl;
81
+ this.keyboardCtrlPromise = null;
82
+ }
83
+ else {
84
+ keyboardCtrl.destroy();
85
+ }
71
86
  }
72
87
  disconnectedCallback() {
88
+ if (this.keyboardCtrlPromise) {
89
+ this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
90
+ this.keyboardCtrlPromise = null;
91
+ }
73
92
  if (this.keyboardCtrl) {
74
93
  this.keyboardCtrl.destroy();
94
+ this.keyboardCtrl = null;
75
95
  }
76
96
  }
77
97
  render() {
78
98
  const { color, translucent, keyboardVisible } = this;
79
99
  const mode = ionicGlobal.getIonMode(this);
80
100
  const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
81
- return (index.h(index.Host, { key: '388ec37ce308035bab78d6c9a016bb616e9517a9', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: theme.createColorClasses(color, {
101
+ return (index.h(index.Host, { key: '9daf4e2acaff6e3ce3878cf9dd5109fb1afbbebe', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: theme.createColorClasses(color, {
82
102
  [mode]: true,
83
103
  'tab-bar-translucent': translucent,
84
104
  'tab-bar-hidden': shouldHide,
85
- }) }, index.h("slot", { key: 'ce10ade2b86725e24f3254516483eeedd8ecb16a' })));
105
+ }) }, index.h("slot", { key: '1d15aa2da8501e8e7eff11ad4a491478be845c43' })));
86
106
  }
87
107
  get el() { return index.getElement(this); }
88
108
  static get watchers() { return {
@@ -451,9 +451,9 @@ const createSwipeToDismissGesture = (el, toastPosition, onDismiss) => {
451
451
  return gesture;
452
452
  };
453
453
 
454
- const toastIosCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-radius:14px;--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--max-width:700px;--max-height:478px;--start:10px;--end:10px;font-size:clamp(14px, 0.875rem, 43.4px)}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;z-index:10}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.toast-translucent) .toast-wrapper{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}:host(.ion-color.toast-translucent) .toast-wrapper{background:rgba(var(--ion-color-base-rgb), 0.8)}}.toast-wrapper.toast-middle{opacity:0.01}.toast-content{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:15px;padding-bottom:15px}.toast-header{margin-bottom:2px;font-weight:500}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;min-height:44px;-webkit-transition:background-color, opacity 100ms linear;transition:background-color, opacity 100ms linear;border:0;background-color:transparent;font-family:var(--ion-font-family);font-size:clamp(17px, 1.0625rem, 21.998px);font-weight:500;overflow:hidden}.toast-button.ion-activated{opacity:0.4}@media (any-hover: hover){.toast-button:hover{opacity:0.6}}";
454
+ const toastIosCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{-ms-flex:1;flex:1;min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-radius:14px;--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--max-width:700px;--max-height:478px;--start:10px;--end:10px;font-size:clamp(14px, 0.875rem, 43.4px)}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;z-index:10}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.toast-translucent) .toast-wrapper{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}:host(.ion-color.toast-translucent) .toast-wrapper{background:rgba(var(--ion-color-base-rgb), 0.8)}}.toast-wrapper.toast-middle{opacity:0.01}.toast-content{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:15px;padding-bottom:15px}.toast-header{margin-bottom:2px;font-weight:500}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;min-height:44px;-webkit-transition:background-color, opacity 100ms linear;transition:background-color, opacity 100ms linear;border:0;background-color:transparent;font-family:var(--ion-font-family);font-size:clamp(17px, 1.0625rem, 21.998px);font-weight:500;overflow:hidden}.toast-button.ion-activated{opacity:0.4}@media (any-hover: hover){.toast-button:hover{opacity:0.6}}";
455
455
 
456
- const toastMdCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-800, var(--ion-background-color-step-800, #333333));--border-radius:4px;--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-50, var(--ion-text-color-step-950, #f2f2f2));--max-width:700px;--start:8px;--end:8px;font-size:0.875rem}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;opacity:0.01;z-index:10}.toast-content{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:14px;padding-bottom:14px}.toast-header{margin-bottom:2px;font-weight:500;line-height:1.25rem}.toast-message{line-height:1.25rem}.toast-layout-baseline .toast-button-group-start{-webkit-margin-start:8px;margin-inline-start:8px}.toast-layout-stacked .toast-button-group-start{-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px}.toast-layout-baseline .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px}.toast-layout-stacked .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px;margin-bottom:8px}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;font-family:var(--ion-font-family);font-size:0.875rem;font-weight:500;letter-spacing:0.84px;text-transform:uppercase;overflow:hidden}.toast-button-cancel{color:var(--ion-color-step-100, var(--ion-text-color-step-900, #e6e6e6))}.toast-button-icon-only{border-radius:50%;-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:9px;padding-bottom:9px;width:36px;height:36px}@media (any-hover: hover){.toast-button:hover{background-color:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08)}.toast-button-cancel:hover{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.08)}}";
456
+ const toastMdCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{-ms-flex:1;flex:1;min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-800, var(--ion-background-color-step-800, #333333));--border-radius:4px;--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-50, var(--ion-text-color-step-950, #f2f2f2));--max-width:700px;--start:8px;--end:8px;font-size:0.875rem}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;opacity:0.01;z-index:10}.toast-content{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:14px;padding-bottom:14px}.toast-header{margin-bottom:2px;font-weight:500;line-height:1.25rem}.toast-message{line-height:1.25rem}.toast-layout-baseline .toast-button-group-start{-webkit-margin-start:8px;margin-inline-start:8px}.toast-layout-stacked .toast-button-group-start{-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px}.toast-layout-baseline .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px}.toast-layout-stacked .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px;margin-bottom:8px}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;font-family:var(--ion-font-family);font-size:0.875rem;font-weight:500;letter-spacing:0.84px;text-transform:uppercase;overflow:hidden}.toast-button-cancel{color:var(--ion-color-step-100, var(--ion-text-color-step-900, #e6e6e6))}.toast-button-icon-only{border-radius:50%;-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:9px;padding-bottom:9px;width:36px;height:36px}@media (any-hover: hover){.toast-button:hover{background-color:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08)}.toast-button-cancel:hover{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.08)}}";
457
457
 
458
458
  const Toast = class {
459
459
  constructor(hostRef) {
@@ -12,6 +12,7 @@ import { handleFooterFade } from "./footer.utils";
12
12
  export class Footer {
13
13
  constructor() {
14
14
  this.keyboardCtrl = null;
15
+ this.keyboardCtrlPromise = null;
15
16
  this.keyboardVisible = false;
16
17
  /**
17
18
  * If `true`, the footer will be translucent.
@@ -59,7 +60,7 @@ export class Footer {
59
60
  this.checkCollapsibleFooter();
60
61
  }
61
62
  async connectedCallback() {
62
- this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
63
+ const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
63
64
  /**
64
65
  * If the keyboard is hiding, then we need to wait
65
66
  * for the webview to resize. Otherwise, the footer
@@ -70,10 +71,29 @@ export class Footer {
70
71
  }
71
72
  this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
72
73
  });
74
+ this.keyboardCtrlPromise = promise;
75
+ const keyboardCtrl = await promise;
76
+ /**
77
+ * Only assign if this is still the current promise.
78
+ * Otherwise, a new connectedCallback has started or
79
+ * disconnectedCallback was called, so destroy this instance.
80
+ */
81
+ if (this.keyboardCtrlPromise === promise) {
82
+ this.keyboardCtrl = keyboardCtrl;
83
+ this.keyboardCtrlPromise = null;
84
+ }
85
+ else {
86
+ keyboardCtrl.destroy();
87
+ }
73
88
  }
74
89
  disconnectedCallback() {
90
+ if (this.keyboardCtrlPromise) {
91
+ this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
92
+ this.keyboardCtrlPromise = null;
93
+ }
75
94
  if (this.keyboardCtrl) {
76
95
  this.keyboardCtrl.destroy();
96
+ this.keyboardCtrl = null;
77
97
  }
78
98
  }
79
99
  destroyCollapsibleFooter() {
@@ -87,7 +107,7 @@ export class Footer {
87
107
  const mode = getIonMode(this);
88
108
  const tabs = this.el.closest('ion-tabs');
89
109
  const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
90
- return (h(Host, { key: 'ddc228f1a1e7fa4f707dccf74db2490ca3241137', role: "contentinfo", class: {
110
+ return (h(Host, { key: '71939c4bbaef5062532a99ee2e33574102a9abad', role: "contentinfo", class: {
91
111
  [mode]: true,
92
112
  // Used internally for styling
93
113
  [`footer-${mode}`]: true,
@@ -95,7 +115,7 @@ export class Footer {
95
115
  [`footer-translucent-${mode}`]: translucent,
96
116
  ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
97
117
  [`footer-collapse-${collapse}`]: collapse !== undefined,
98
- } }, mode === 'ios' && translucent && h("div", { key: 'e16ed4963ff94e06de77eb8038201820af73937c', class: "footer-background" }), h("slot", { key: 'f186934febf85d37133d9351a96c1a64b0a4b203' })));
118
+ } }, mode === 'ios' && translucent && h("div", { key: '2fa14f61661c47c661cecd696176728d6eafa74f', class: "footer-background" }), h("slot", { key: '8e63696e7c528d5c38201e546bf08135290d0945' })));
99
119
  }
100
120
  static get is() { return "ion-footer"; }
101
121
  static get originalStyleUrls() {