@ionic/vue 8.2.8-dev.11725452518.16aa47d3 → 8.2.8-dev.11725551009.1bc973e7

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 (56) hide show
  1. package/css/core.css +1 -1
  2. package/css/core.css.map +1 -1
  3. package/css/display.css.map +1 -1
  4. package/css/flex-utils.css.map +1 -1
  5. package/css/float-elements.css.map +1 -1
  6. package/css/global.bundle.css +1 -1
  7. package/css/global.bundle.css.map +1 -1
  8. package/css/ionic-swiper.css +1 -1
  9. package/css/ionic-swiper.css.map +1 -1
  10. package/css/ionic.bundle.css +1 -1
  11. package/css/ionic.bundle.css.map +1 -1
  12. package/css/normalize.css.map +1 -1
  13. package/css/padding.css.map +1 -1
  14. package/css/palettes/dark.always.css.map +1 -1
  15. package/css/palettes/dark.class.css.map +1 -1
  16. package/css/palettes/dark.system.css.map +1 -1
  17. package/css/palettes/high-contrast-dark.always.css.map +1 -1
  18. package/css/palettes/high-contrast-dark.class.css.map +1 -1
  19. package/css/palettes/high-contrast-dark.system.css.map +1 -1
  20. package/css/palettes/high-contrast.always.css.map +1 -1
  21. package/css/palettes/high-contrast.class.css.map +1 -1
  22. package/css/palettes/high-contrast.system.css.map +1 -1
  23. package/css/structure.css +1 -1
  24. package/css/structure.css.map +1 -1
  25. package/css/text-alignment.css.map +1 -1
  26. package/css/text-transformation.css.map +1 -1
  27. package/css/typography.css +1 -1
  28. package/css/typography.css.map +1 -1
  29. package/css/utils.bundle.css.map +1 -1
  30. package/dist/index.js +210 -116
  31. package/dist/index.js.map +1 -1
  32. package/dist/types/components/IonTabBar.d.ts +29 -0
  33. package/dist/types/components/IonTabButton.d.ts +8 -0
  34. package/dist/types/components/IonTabs.d.ts +10 -1
  35. package/dist/types/components/Overlays.d.ts +1 -1
  36. package/dist/types/proxies.d.ts +1 -0
  37. package/dist/vetur/attributes.json +108 -1346
  38. package/dist/vetur/tags.json +45 -193
  39. package/dist/web-types.json +122 -1305
  40. package/package.json +2 -2
  41. package/css/ionic/bundle.ionic.css +0 -1
  42. package/css/ionic/bundle.ionic.css.map +0 -1
  43. package/css/ionic/core.ionic.css +0 -1
  44. package/css/ionic/core.ionic.css.map +0 -1
  45. package/css/ionic/global.bundle.ionic.css +0 -1
  46. package/css/ionic/global.bundle.ionic.css.map +0 -1
  47. package/css/ionic/ionic-swiper.ionic.css +0 -1
  48. package/css/ionic/ionic-swiper.ionic.css.map +0 -1
  49. package/css/ionic/link.ionic.css +0 -1
  50. package/css/ionic/link.ionic.css.map +0 -1
  51. package/css/ionic/structure.ionic.css +0 -1
  52. package/css/ionic/structure.ionic.css.map +0 -1
  53. package/css/ionic/typography.ionic.css +0 -1
  54. package/css/ionic/typography.ionic.css.map +0 -1
  55. package/css/ionic/utils.bundle.ionic.css +0 -1
  56. package/css/ionic/utils.bundle.ionic.css.map +0 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, getCurrentInstance, inject, h, withDirectives, computed, provide, shallowRef, watch, onUnmounted, Teleport, onMounted } from 'vue';
1
+ import { defineComponent, ref, getCurrentInstance, inject, h, withDirectives, computed, provide, shallowRef, watch, onUnmounted, Fragment, isVNode, Teleport, onMounted } from 'vue';
2
2
  import { defineCustomElement } from '@ionic/core/components/ion-accordion.js';
3
3
  import { defineCustomElement as defineCustomElement$1 } from '@ionic/core/components/ion-accordion-group.js';
4
4
  import { defineCustomElement as defineCustomElement$2 } from '@ionic/core/components/ion-avatar.js';
@@ -42,7 +42,7 @@ import { defineCustomElement as defineCustomElement$D } from '@ionic/core/compon
42
42
  import { defineCustomElement as defineCustomElement$E } from '@ionic/core/components/ion-menu.js';
43
43
  import { defineCustomElement as defineCustomElement$F } from '@ionic/core/components/ion-menu-button.js';
44
44
  import { defineCustomElement as defineCustomElement$G } from '@ionic/core/components/ion-menu-toggle.js';
45
- import { defineCustomElement as defineCustomElement$1d } from '@ionic/core/components/ion-nav.js';
45
+ import { defineCustomElement as defineCustomElement$1f } from '@ionic/core/components/ion-nav.js';
46
46
  import { defineCustomElement as defineCustomElement$H } from '@ionic/core/components/ion-nav-link.js';
47
47
  import { defineCustomElement as defineCustomElement$I } from '@ionic/core/components/ion-note.js';
48
48
  import { defineCustomElement as defineCustomElement$J } from '@ionic/core/components/ion-picker.js';
@@ -66,28 +66,30 @@ import { defineCustomElement as defineCustomElement$_ } from '@ionic/core/compon
66
66
  import { defineCustomElement as defineCustomElement$$ } from '@ionic/core/components/ion-skeleton-text.js';
67
67
  import { defineCustomElement as defineCustomElement$10 } from '@ionic/core/components/ion-spinner.js';
68
68
  import { defineCustomElement as defineCustomElement$11 } from '@ionic/core/components/ion-split-pane.js';
69
- import { defineCustomElement as defineCustomElement$12 } from '@ionic/core/components/ion-text.js';
70
- import { defineCustomElement as defineCustomElement$13 } from '@ionic/core/components/ion-textarea.js';
71
- import { defineCustomElement as defineCustomElement$14 } from '@ionic/core/components/ion-thumbnail.js';
72
- import { defineCustomElement as defineCustomElement$15 } from '@ionic/core/components/ion-title.js';
73
- import { defineCustomElement as defineCustomElement$16 } from '@ionic/core/components/ion-toggle.js';
74
- import { defineCustomElement as defineCustomElement$17 } from '@ionic/core/components/ion-toolbar.js';
69
+ import { defineCustomElement as defineCustomElement$12 } from '@ionic/core/components/ion-tab.js';
70
+ import { defineCustomElement as defineCustomElement$13 } from '@ionic/core/components/ion-text.js';
71
+ import { defineCustomElement as defineCustomElement$14 } from '@ionic/core/components/ion-textarea.js';
72
+ import { defineCustomElement as defineCustomElement$15 } from '@ionic/core/components/ion-thumbnail.js';
73
+ import { defineCustomElement as defineCustomElement$16 } from '@ionic/core/components/ion-title.js';
74
+ import { defineCustomElement as defineCustomElement$17 } from '@ionic/core/components/ion-toggle.js';
75
+ import { defineCustomElement as defineCustomElement$18 } from '@ionic/core/components/ion-toolbar.js';
75
76
  import { LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, initialize, modalController as modalController$1, popoverController as popoverController$1, alertController as alertController$1, actionSheetController as actionSheetController$1, loadingController as loadingController$1, pickerController as pickerController$1, toastController as toastController$1 } from '@ionic/core/components';
76
77
  export { IonicSafeString, IonicSlides, createAnimation, createGesture, getIonPageElement, getPlatforms, getTimeGivenProgression, iosTransitionAnimation, isPlatform, mdTransitionAnimation, menuController, openURL } from '@ionic/core/components';
77
- import { defineCustomElement as defineCustomElement$18 } from '@ionic/core/components/ion-back-button.js';
78
- import { defineCustomElement as defineCustomElement$19 } from '@ionic/core/components/ion-router-outlet.js';
78
+ import { defineCustomElement as defineCustomElement$19 } from '@ionic/core/components/ion-back-button.js';
79
+ import { defineCustomElement as defineCustomElement$1a } from '@ionic/core/components/ion-router-outlet.js';
79
80
  import { routeLocationKey, useRoute, matchedRouteKey } from 'vue-router';
80
- import { defineCustomElement as defineCustomElement$1a } from '@ionic/core/components/ion-tab-button.js';
81
- import { defineCustomElement as defineCustomElement$1b } from '@ionic/core/components/ion-tab-bar.js';
82
- import { defineCustomElement as defineCustomElement$1c } from '@ionic/core/components/ion-app.js';
83
- import { defineCustomElement as defineCustomElement$1e } from 'ionicons/components/ion-icon.js';
84
- import { defineCustomElement as defineCustomElement$1f } from '@ionic/core/components/ion-action-sheet.js';
85
- import { defineCustomElement as defineCustomElement$1g } from '@ionic/core/components/ion-alert.js';
86
- import { defineCustomElement as defineCustomElement$1h } from '@ionic/core/components/ion-loading.js';
87
- import { defineCustomElement as defineCustomElement$1i } from '@ionic/core/components/ion-picker-legacy.js';
88
- import { defineCustomElement as defineCustomElement$1j } from '@ionic/core/components/ion-toast.js';
89
- import { defineCustomElement as defineCustomElement$1k } from '@ionic/core/components/ion-modal.js';
90
- import { defineCustomElement as defineCustomElement$1l } from '@ionic/core/components/ion-popover.js';
81
+ import { defineCustomElement as defineCustomElement$1b } from '@ionic/core/components/ion-tab-button.js';
82
+ import { defineCustomElement as defineCustomElement$1c } from '@ionic/core/components/ion-tabs.js';
83
+ import { defineCustomElement as defineCustomElement$1d } from '@ionic/core/components/ion-tab-bar.js';
84
+ import { defineCustomElement as defineCustomElement$1e } from '@ionic/core/components/ion-app.js';
85
+ import { defineCustomElement as defineCustomElement$1g } from 'ionicons/components/ion-icon.js';
86
+ import { defineCustomElement as defineCustomElement$1h } from '@ionic/core/components/ion-action-sheet.js';
87
+ import { defineCustomElement as defineCustomElement$1i } from '@ionic/core/components/ion-alert.js';
88
+ import { defineCustomElement as defineCustomElement$1j } from '@ionic/core/components/ion-loading.js';
89
+ import { defineCustomElement as defineCustomElement$1k } from '@ionic/core/components/ion-picker-legacy.js';
90
+ import { defineCustomElement as defineCustomElement$1l } from '@ionic/core/components/ion-toast.js';
91
+ import { defineCustomElement as defineCustomElement$1m } from '@ionic/core/components/ion-modal.js';
92
+ import { defineCustomElement as defineCustomElement$1n } from '@ionic/core/components/ion-popover.js';
91
93
 
92
94
  // @ts-nocheck
93
95
  // It's easier and safer for Volar to disable typechecking and let the return type inference do its job.
@@ -297,10 +299,7 @@ const IonAccordionGroup = /*@__PURE__*/ defineContainer('ion-accordion-group', d
297
299
  'ionChange',
298
300
  'ionValueChange'
299
301
  ], 'value', 'ion-change');
300
- const IonAvatar = /*@__PURE__*/ defineContainer('ion-avatar', defineCustomElement$2, [
301
- 'size',
302
- 'shape'
303
- ]);
302
+ const IonAvatar = /*@__PURE__*/ defineContainer('ion-avatar', defineCustomElement$2);
304
303
  const IonBackdrop = /*@__PURE__*/ defineContainer('ion-backdrop', defineCustomElement$3, [
305
304
  'visible',
306
305
  'tappable',
@@ -308,9 +307,7 @@ const IonBackdrop = /*@__PURE__*/ defineContainer('ion-backdrop', defineCustomEl
308
307
  'ionBackdropTap'
309
308
  ]);
310
309
  const IonBadge = /*@__PURE__*/ defineContainer('ion-badge', defineCustomElement$4, [
311
- 'color',
312
- 'shape',
313
- 'size'
310
+ 'color'
314
311
  ]);
315
312
  const IonBreadcrumb = /*@__PURE__*/ defineContainer('ion-breadcrumb', defineCustomElement$5, [
316
313
  'collapsed',
@@ -370,7 +367,6 @@ const IonCard = /*@__PURE__*/ defineContainer('ion-card', defineCustomElement$9,
370
367
  'rel',
371
368
  'routerDirection',
372
369
  'routerAnimation',
373
- 'shape',
374
370
  'target'
375
371
  ]);
376
372
  const IonCardContent = /*@__PURE__*/ defineContainer('ion-card-content', defineCustomElement$a);
@@ -394,8 +390,6 @@ const IonCheckbox = /*@__PURE__*/ defineContainer('ion-checkbox', defineCustomEl
394
390
  'labelPlacement',
395
391
  'justify',
396
392
  'alignment',
397
- 'size',
398
- 'shape',
399
393
  'ionChange',
400
394
  'ionFocus',
401
395
  'ionBlur'
@@ -403,9 +397,7 @@ const IonCheckbox = /*@__PURE__*/ defineContainer('ion-checkbox', defineCustomEl
403
397
  const IonChip = /*@__PURE__*/ defineContainer('ion-chip', defineCustomElement$f, [
404
398
  'color',
405
399
  'outline',
406
- 'disabled',
407
- 'shape',
408
- 'size'
400
+ 'disabled'
409
401
  ]);
410
402
  const IonCol = /*@__PURE__*/ defineContainer('ion-col', defineCustomElement$g, [
411
403
  'offset',
@@ -526,7 +518,6 @@ const IonGrid = /*@__PURE__*/ defineContainer('ion-grid', defineCustomElement$o,
526
518
  ]);
527
519
  const IonHeader = /*@__PURE__*/ defineContainer('ion-header', defineCustomElement$p, [
528
520
  'collapse',
529
- 'divider',
530
521
  'translucent'
531
522
  ]);
532
523
  const IonImg = /*@__PURE__*/ defineContainer('ion-img', defineCustomElement$q, [
@@ -579,7 +570,6 @@ const IonInput = /*@__PURE__*/ defineContainer('ion-input', defineCustomElement$
579
570
  'shape',
580
571
  'spellcheck',
581
572
  'step',
582
- 'size',
583
573
  'type',
584
574
  'value',
585
575
  'ionInput',
@@ -621,8 +611,7 @@ const IonItemOption = /*@__PURE__*/ defineContainer('ion-item-option', defineCus
621
611
  'href',
622
612
  'rel',
623
613
  'target',
624
- 'type',
625
- 'shape'
614
+ 'type'
626
615
  ]);
627
616
  const IonItemOptions = /*@__PURE__*/ defineContainer('ion-item-options', defineCustomElement$z, [
628
617
  'side',
@@ -640,8 +629,7 @@ const IonLabel = /*@__PURE__*/ defineContainer('ion-label', defineCustomElement$
640
629
  ]);
641
630
  const IonList = /*@__PURE__*/ defineContainer('ion-list', defineCustomElement$C, [
642
631
  'lines',
643
- 'inset',
644
- 'shape'
632
+ 'inset'
645
633
  ]);
646
634
  const IonListHeader = /*@__PURE__*/ defineContainer('ion-list-header', defineCustomElement$D, [
647
635
  'color',
@@ -859,8 +847,7 @@ const IonSpinner = /*@__PURE__*/ defineContainer('ion-spinner', defineCustomElem
859
847
  'color',
860
848
  'duration',
861
849
  'name',
862
- 'paused',
863
- 'size'
850
+ 'paused'
864
851
  ]);
865
852
  const IonSplitPane = /*@__PURE__*/ defineContainer('ion-split-pane', defineCustomElement$11, [
866
853
  'contentId',
@@ -868,10 +855,16 @@ const IonSplitPane = /*@__PURE__*/ defineContainer('ion-split-pane', defineCusto
868
855
  'when',
869
856
  'ionSplitPaneVisible'
870
857
  ]);
871
- const IonText = /*@__PURE__*/ defineContainer('ion-text', defineCustomElement$12, [
858
+ const IonTab = /*@__PURE__*/ defineContainer('ion-tab', defineCustomElement$12, [
859
+ 'active',
860
+ 'delegate',
861
+ 'tab',
862
+ 'component'
863
+ ]);
864
+ const IonText = /*@__PURE__*/ defineContainer('ion-text', defineCustomElement$13, [
872
865
  'color'
873
866
  ]);
874
- const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomElement$13, [
867
+ const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomElement$14, [
875
868
  'color',
876
869
  'autocapitalize',
877
870
  'autofocus',
@@ -900,19 +893,18 @@ const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomEl
900
893
  'label',
901
894
  'labelPlacement',
902
895
  'shape',
903
- 'size',
904
896
  'ionChange',
905
897
  'ionInput',
906
898
  'ionBlur',
907
899
  'ionFocus'
908
900
  ], 'value', 'ion-input');
909
- const IonThumbnail = /*@__PURE__*/ defineContainer('ion-thumbnail', defineCustomElement$14);
910
- const IonTitle = /*@__PURE__*/ defineContainer('ion-title', defineCustomElement$15, [
901
+ const IonThumbnail = /*@__PURE__*/ defineContainer('ion-thumbnail', defineCustomElement$15);
902
+ const IonTitle = /*@__PURE__*/ defineContainer('ion-title', defineCustomElement$16, [
911
903
  'color',
912
904
  'size',
913
905
  'ionStyle'
914
906
  ]);
915
- const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElement$16, [
907
+ const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElement$17, [
916
908
  'color',
917
909
  'name',
918
910
  'checked',
@@ -926,7 +918,7 @@ const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElemen
926
918
  'ionFocus',
927
919
  'ionBlur'
928
920
  ], 'checked', 'ion-change');
929
- const IonToolbar = /*@__PURE__*/ defineContainer('ion-toolbar', defineCustomElement$17, [
921
+ const IonToolbar = /*@__PURE__*/ defineContainer('ion-toolbar', defineCustomElement$18, [
930
922
  'color'
931
923
  ]);
932
924
 
@@ -1104,7 +1096,7 @@ const IonicVue = {
1104
1096
  };
1105
1097
 
1106
1098
  const IonBackButton = /*@__PURE__*/ defineComponent((_, { attrs, slots }) => {
1107
- defineCustomElement$18();
1099
+ defineCustomElement$19();
1108
1100
  // TODO(FW-2969): type
1109
1101
  const ionRouter = inject("navManager");
1110
1102
  const onClick = () => {
@@ -1150,7 +1142,7 @@ const viewDepthKey = Symbol(0);
1150
1142
  const IonRouterOutlet = /*@__PURE__*/ defineComponent({
1151
1143
  name: "IonRouterOutlet",
1152
1144
  setup() {
1153
- defineCustomElement$19();
1145
+ defineCustomElement$1a();
1154
1146
  const injectedRoute = inject(routeLocationKey);
1155
1147
  const route = useRoute();
1156
1148
  const depth = inject(viewDepthKey, 0);
@@ -1584,9 +1576,13 @@ const IonTabButton = /*@__PURE__*/ defineComponent({
1584
1576
  selected: Boolean,
1585
1577
  tab: String,
1586
1578
  target: String,
1579
+ _onClick: {
1580
+ type: Function,
1581
+ required: false,
1582
+ },
1587
1583
  },
1588
1584
  setup(props, { slots }) {
1589
- defineCustomElement$1a();
1585
+ defineCustomElement$1b();
1590
1586
  // TODO(FW-2969): type
1591
1587
  const ionRouter = inject("navManager");
1592
1588
  const onClick = (ev) => {
@@ -1601,10 +1597,25 @@ const IonTabButton = /*@__PURE__*/ defineComponent({
1601
1597
  */
1602
1598
  const { tab, href, _getTabState } = props;
1603
1599
  const tabState = _getTabState();
1600
+ const hasRouterOutlet = tabState.hasRouterOutlet;
1604
1601
  const tappedTab = tabState.tabs[tab] || {};
1605
1602
  const originalHref = tappedTab.originalHref || href;
1606
- const currentHref = tappedTab.currentHref || href;
1603
+ /**
1604
+ * If the router outlet is not defined, then the tabs is being used
1605
+ * as a basic tab navigation without the router. In this case, we
1606
+ * don't want to update the href else the URL will change.
1607
+ */
1608
+ const currentHref = hasRouterOutlet ? tappedTab.currentHref || href : "";
1607
1609
  const prevActiveTab = tabState.activeTab;
1610
+ if (!hasRouterOutlet && props._onClick) {
1611
+ props._onClick(new CustomEvent("ionTabButtonClick", {
1612
+ detail: {
1613
+ href: currentHref,
1614
+ selected: tab === prevActiveTab,
1615
+ tab,
1616
+ },
1617
+ }));
1618
+ }
1608
1619
  /**
1609
1620
  * If we are still on the same
1610
1621
  * tab as before, but the base href
@@ -1647,47 +1658,67 @@ const isTabBar = (node) => {
1647
1658
  return (node.type &&
1648
1659
  (node.type.name === "IonTabBar" || node.type === "ion-tab-bar"));
1649
1660
  };
1661
+ const isTab = (node) => {
1662
+ // The `ion-tab` component was created with the `v-for` directive.
1663
+ if (node.type === Fragment) {
1664
+ if (Array.isArray(node.children)) {
1665
+ return node.children.some((child) => isVNode(child) && isTab(child));
1666
+ }
1667
+ return false; // In case the fragment has no children.
1668
+ }
1669
+ return (node.type && (node.type.name === "ion-tab" || node.type === IonTab));
1670
+ };
1650
1671
  const IonTabs = /*@__PURE__*/ defineComponent({
1651
1672
  name: "IonTabs",
1652
1673
  emits: [WILL_CHANGE, DID_CHANGE],
1674
+ setup(props, { slots, emit }) {
1675
+ return {
1676
+ props,
1677
+ slots,
1678
+ emit,
1679
+ };
1680
+ },
1681
+ mounted() {
1682
+ /**
1683
+ * `defineCustomElement` must be called in the `mounted` hook
1684
+ * to ensure that the custom element is defined after the
1685
+ * component has been fully rendered and initialized.
1686
+ * This prevents issues with undefined properties, like
1687
+ * `selectedTab` from core, which may occur if the custom
1688
+ * element is defined too early in the component's lifecycle.
1689
+ */
1690
+ defineCustomElement$1c();
1691
+ },
1653
1692
  render() {
1654
- var _a;
1655
- const { $slots: slots, $emit } = this;
1693
+ const { slots, emit, props } = this;
1656
1694
  const slottedContent = slots.default && slots.default();
1657
1695
  let routerOutlet;
1658
- /**
1659
- * Developers must pass an ion-router-outlet
1660
- * inside of ion-tabs.
1661
- */
1696
+ let hasTab = false;
1662
1697
  if (slottedContent && slottedContent.length > 0) {
1698
+ /**
1699
+ * Developers must pass an ion-router-outlet
1700
+ * inside of ion-tabs if they want to use
1701
+ * the history stack or URL updates associated
1702
+ * wit the router.
1703
+ */
1663
1704
  routerOutlet = slottedContent.find((child) => isRouterOutlet(child));
1705
+ /**
1706
+ * Developers must pass at least one ion-tab
1707
+ * inside of ion-tabs if they want to use a
1708
+ * basic tab-based navigation without the
1709
+ * history stack or URL updates associated
1710
+ * with the router.
1711
+ */
1712
+ hasTab = slottedContent.some((child) => isTab(child));
1664
1713
  }
1665
- if (!routerOutlet) {
1666
- throw new Error("IonTabs must contain an IonRouterOutlet. See https://ionicframework.com/docs/vue/navigation#working-with-tabs for more information.");
1714
+ if (!routerOutlet && !hasTab) {
1715
+ throw new Error("IonTabs must contain an IonRouterOutlet or an IonTab.");
1716
+ }
1717
+ if (routerOutlet && hasTab) {
1718
+ throw new Error("IonTabs cannot contain an IonRouterOutlet and IonTab at the same time.");
1667
1719
  }
1668
- let childrenToRender = [
1669
- h("div", {
1670
- class: "tabs-inner",
1671
- style: {
1672
- position: "relative",
1673
- flex: "1",
1674
- contain: "layout size style",
1675
- },
1676
- }, routerOutlet),
1677
- ];
1678
- /**
1679
- * If ion-tab-bar has slot="top" it needs to be
1680
- * rendered before `.tabs-inner` otherwise it will
1681
- * not show above the tab content.
1682
- */
1683
1720
  if (slottedContent && slottedContent.length > 0) {
1684
- /**
1685
- * Render all content except for router outlet
1686
- * since that needs to be inside of `.tabs-inner`.
1687
- */
1688
- const filteredContent = slottedContent.filter((child) => !child.type || !isRouterOutlet(child));
1689
- const slottedTabBar = filteredContent.find((child) => isTabBar(child));
1690
- const hasTopSlotTabBar = slottedTabBar && ((_a = slottedTabBar.props) === null || _a === void 0 ? void 0 : _a.slot) === "top";
1721
+ const slottedTabBar = slottedContent.find((child) => isTabBar(child));
1691
1722
  if (slottedTabBar) {
1692
1723
  if (!slottedTabBar.props) {
1693
1724
  slottedTabBar.props = {};
@@ -1699,16 +1730,24 @@ const IonTabs = /*@__PURE__*/ defineComponent({
1699
1730
  * TODO: We may want to move logic from the tab bar into here
1700
1731
  * so we do not have code split across two components.
1701
1732
  */
1702
- slottedTabBar.props._tabsWillChange = (tab) => $emit(WILL_CHANGE, { tab });
1703
- slottedTabBar.props._tabsDidChange = (tab) => $emit(DID_CHANGE, { tab });
1704
- }
1705
- if (hasTopSlotTabBar) {
1706
- childrenToRender = [...filteredContent, ...childrenToRender];
1707
- }
1708
- else {
1709
- childrenToRender = [...childrenToRender, ...filteredContent];
1733
+ slottedTabBar.props._tabsWillChange = (tab) => emit(WILL_CHANGE, { tab });
1734
+ slottedTabBar.props._tabsDidChange = (tab) => emit(DID_CHANGE, { tab });
1735
+ slottedTabBar.props._hasRouterOutlet = !!routerOutlet;
1710
1736
  }
1711
1737
  }
1738
+ if (hasTab) {
1739
+ return h("ion-tabs", Object.assign({}, props), slottedContent);
1740
+ }
1741
+ /**
1742
+ * TODO(ROU-11056)
1743
+ *
1744
+ * Vue handles the error case for when there is no
1745
+ * associated page matching the tab `href`.
1746
+ *
1747
+ * More investigation is needed to determine if we
1748
+ * override the error handling and provide our own
1749
+ * error message.
1750
+ */
1712
1751
  return h("ion-tabs", {
1713
1752
  style: {
1714
1753
  display: "flex",
@@ -1723,7 +1762,7 @@ const IonTabs = /*@__PURE__*/ defineComponent({
1723
1762
  contain: "layout size style",
1724
1763
  "z-index": "0",
1725
1764
  },
1726
- }, childrenToRender);
1765
+ }, slottedContent);
1727
1766
  },
1728
1767
  });
1729
1768
 
@@ -1747,6 +1786,7 @@ const IonTabBar = defineComponent({
1747
1786
  /* eslint-disable @typescript-eslint/no-empty-function */
1748
1787
  _tabsWillChange: { type: Function, default: () => { } },
1749
1788
  _tabsDidChange: { type: Function, default: () => { } },
1789
+ _hasRouterOutlet: { type: Boolean, default: false },
1750
1790
  /* eslint-enable @typescript-eslint/no-empty-function */
1751
1791
  },
1752
1792
  data() {
@@ -1763,6 +1803,7 @@ const IonTabBar = defineComponent({
1763
1803
  },
1764
1804
  methods: {
1765
1805
  setupTabState(ionRouter) {
1806
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1766
1807
  /**
1767
1808
  * For each tab, we need to keep track of its
1768
1809
  * base href as well as any child page that
@@ -1779,25 +1820,65 @@ const IonTabBar = defineComponent({
1779
1820
  currentHref: child.props.href,
1780
1821
  ref: child,
1781
1822
  };
1823
+ /**
1824
+ * Passing this prop to each tab button
1825
+ * lets it be aware of the presence of
1826
+ * the router outlet.
1827
+ */
1828
+ tabState.hasRouterOutlet = hasRouterOutlet;
1782
1829
  /**
1783
1830
  * Passing this prop to each tab button
1784
1831
  * lets it be aware of the state that
1785
1832
  * ion-tab-bar is managing for it.
1786
1833
  */
1787
1834
  child.component.props._getTabState = () => tabState;
1835
+ /**
1836
+ * If the router outlet is not defined, then the tabs are being used
1837
+ * as a basic tab navigation without the router. In this case, the
1838
+ * tabs will not emit the `ionTabsDidChange` and `ionTabsWillChange`
1839
+ * events through the `checkActiveTab` method. Instead, we need to
1840
+ * handle those events through the tab buttons.
1841
+ */
1842
+ if (!hasRouterOutlet) {
1843
+ child.component.props._onClick = (event) => {
1844
+ this.handleIonTabButtonClick(event);
1845
+ };
1846
+ }
1788
1847
  });
1789
1848
  this.checkActiveTab(ionRouter);
1790
1849
  },
1850
+ /**
1851
+ * This method is called upon setup and when the
1852
+ * history changes. It checks the current route
1853
+ * and updates the active tab accordingly.
1854
+ *
1855
+ * History changes only occur when the router
1856
+ * outlet is present. Due to this, the
1857
+ * `ionTabsDidChange` and `ionTabsWillChange`
1858
+ * events are only emitted when the router
1859
+ * outlet is present. A different approach must
1860
+ * be taken for tabs without a router outlet.
1861
+ *
1862
+ * @param ionRouter
1863
+ */
1791
1864
  checkActiveTab(ionRouter) {
1865
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1792
1866
  const currentRoute = ionRouter.getCurrentRouteInfo();
1793
1867
  const childNodes = this.$data.tabVnodes;
1794
1868
  const { tabs, activeTab: prevActiveTab } = this.$data.tabState;
1795
- const tabState = this.$data.tabState;
1796
1869
  const tabKeys = Object.keys(tabs);
1797
- const activeTab = tabKeys.find((key) => {
1870
+ let activeTab = tabKeys.find((key) => {
1798
1871
  const href = tabs[key].originalHref;
1799
1872
  return currentRoute.pathname.startsWith(href);
1800
1873
  });
1874
+ /**
1875
+ * Tabs is being used as a basic tab navigation,
1876
+ * so we need to set the first tab as active since
1877
+ * `checkActiveTab` will not be called after setup.
1878
+ */
1879
+ if (!activeTab && !hasRouterOutlet) {
1880
+ activeTab = tabKeys[0];
1881
+ }
1801
1882
  /**
1802
1883
  * For each tab, check to see if the
1803
1884
  * base href has changed. If so, update
@@ -1841,23 +1922,36 @@ const IonTabBar = defineComponent({
1841
1922
  tabs[prevActiveTab] = Object.assign(Object.assign({}, tabs[prevActiveTab]), { currentHref: tabs[prevActiveTab].originalHref });
1842
1923
  }
1843
1924
  }
1925
+ this.tabSwitch(activeTab, ionRouter);
1926
+ },
1927
+ handleIonTabButtonClick(event) {
1928
+ const activeTab = event.detail.tab;
1929
+ this.tabSwitch(activeTab);
1930
+ },
1931
+ tabSwitch(activeTab, ionRouter) {
1932
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1933
+ const childNodes = this.$data.tabVnodes;
1934
+ const { activeTab: prevActiveTab } = this.$data.tabState;
1935
+ const tabState = this.$data.tabState;
1844
1936
  const activeChild = childNodes.find((child) => { var _a; return isTabButton(child) && ((_a = child.props) === null || _a === void 0 ? void 0 : _a.tab) === activeTab; });
1845
1937
  const tabBar = this.$refs.ionTabBar;
1846
1938
  const tabDidChange = activeTab !== prevActiveTab;
1847
1939
  if (tabBar) {
1848
1940
  if (activeChild) {
1849
1941
  tabDidChange && this.$props._tabsWillChange(activeTab);
1850
- ionRouter.handleSetCurrentTab(activeTab);
1942
+ if (hasRouterOutlet && ionRouter) {
1943
+ ionRouter.handleSetCurrentTab(activeTab);
1944
+ }
1851
1945
  tabBar.selectedTab = tabState.activeTab = activeTab;
1852
1946
  tabDidChange && this.$props._tabsDidChange(activeTab);
1947
+ }
1948
+ else {
1853
1949
  /**
1854
1950
  * When going to a tab that does
1855
1951
  * not have an associated ion-tab-button
1856
1952
  * we need to remove the selected state from
1857
1953
  * the old tab.
1858
1954
  */
1859
- }
1860
- else {
1861
1955
  tabBar.selectedTab = tabState.activeTab = "";
1862
1956
  }
1863
1957
  }
@@ -1869,7 +1963,7 @@ const IonTabBar = defineComponent({
1869
1963
  ionRouter.registerHistoryChangeListener(() => this.checkActiveTab(ionRouter));
1870
1964
  },
1871
1965
  setup(_, { slots }) {
1872
- defineCustomElement$1b();
1966
+ defineCustomElement$1d();
1873
1967
  return () => {
1874
1968
  return h("ion-tab-bar", { ref: "ionTabBar" }, slots.default && slots.default());
1875
1969
  };
@@ -1878,7 +1972,7 @@ const IonTabBar = defineComponent({
1878
1972
 
1879
1973
  const userComponents = shallowRef([]);
1880
1974
  const IonApp = /*@__PURE__*/ defineComponent((_, { attrs, slots }) => {
1881
- defineCustomElement$1c();
1975
+ defineCustomElement$1e();
1882
1976
  return () => {
1883
1977
  return h("ion-app", Object.assign({}, attrs), [slots.default && slots.default(), ...userComponents.value]);
1884
1978
  };
@@ -1930,7 +2024,7 @@ const VueDelegate = (addFn = addTeleportedUserComponent, removeFn = removeTelepo
1930
2024
  };
1931
2025
 
1932
2026
  const IonNav = /*@__PURE__*/ defineComponent((props) => {
1933
- defineCustomElement$1d();
2027
+ defineCustomElement$1f();
1934
2028
  const views = shallowRef([]);
1935
2029
  /**
1936
2030
  * Allows us to create the component
@@ -1990,7 +2084,7 @@ const IonIcon = /*@__PURE__*/ defineComponent({
1990
2084
  src: String,
1991
2085
  },
1992
2086
  setup(props, { slots }) {
1993
- defineCustomElement$1e();
2087
+ defineCustomElement$1g();
1994
2088
  return () => {
1995
2089
  var _a, _b;
1996
2090
  const { icon, ios, md, mode } = props;
@@ -2179,13 +2273,13 @@ const defineOverlayContainer = (name, defineCustomElement, componentProps = [],
2179
2273
  * This is an autogenerated file created by 'scripts/copy-overlays.js'.
2180
2274
  * Changes made to this file will be overwritten on build.
2181
2275
  */
2182
- const IonActionSheet = /*@__PURE__*/ defineOverlayContainer('ion-action-sheet', defineCustomElement$1f, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'theme', 'translucent', 'trigger']);
2183
- const IonAlert = /*@__PURE__*/ defineOverlayContainer('ion-alert', defineCustomElement$1g, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'theme', 'translucent', 'trigger']);
2184
- const IonLoading = /*@__PURE__*/ defineOverlayContainer('ion-loading', defineCustomElement$1h, ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'theme', 'translucent', 'trigger']);
2185
- const IonPickerLegacy = /*@__PURE__*/ defineOverlayContainer('ion-picker-legacy', defineCustomElement$1i, ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'theme', 'trigger']);
2186
- const IonToast = /*@__PURE__*/ defineOverlayContainer('ion-toast', defineCustomElement$1j, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'theme', 'translucent', 'trigger']);
2187
- const IonModal = /*@__PURE__*/ defineOverlayContainer('ion-modal', defineCustomElement$1k, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'focusTrap', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'theme', 'trigger'], true);
2188
- const IonPopover = /*@__PURE__*/ defineOverlayContainer('ion-popover', defineCustomElement$1l, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'focusTrap', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'theme', 'translucent', 'trigger', 'triggerAction']);
2276
+ const IonActionSheet = /*@__PURE__*/ defineOverlayContainer('ion-action-sheet', defineCustomElement$1h, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'translucent', 'trigger']);
2277
+ const IonAlert = /*@__PURE__*/ defineOverlayContainer('ion-alert', defineCustomElement$1i, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'translucent', 'trigger']);
2278
+ const IonLoading = /*@__PURE__*/ defineOverlayContainer('ion-loading', defineCustomElement$1j, ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'translucent', 'trigger']);
2279
+ const IonPickerLegacy = /*@__PURE__*/ defineOverlayContainer('ion-picker-legacy', defineCustomElement$1k, ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger']);
2280
+ const IonToast = /*@__PURE__*/ defineOverlayContainer('ion-toast', defineCustomElement$1l, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'translucent', 'trigger']);
2281
+ const IonModal = /*@__PURE__*/ defineOverlayContainer('ion-modal', defineCustomElement$1m, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'focusTrap', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'trigger'], true);
2282
+ const IonPopover = /*@__PURE__*/ defineOverlayContainer('ion-popover', defineCustomElement$1n, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'focusTrap', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']);
2189
2283
 
2190
2284
  // TODO(FW-2969): types
2191
2285
  /**
@@ -2202,16 +2296,16 @@ const createController = (defineCustomElement, oldController, useDelegate = fals
2202
2296
  };
2203
2297
  return oldController;
2204
2298
  };
2205
- const modalController = /*@__PURE__*/ createController(defineCustomElement$1k, modalController$1, true);
2206
- const popoverController = /*@__PURE__*/ createController(defineCustomElement$1l, popoverController$1, true);
2207
- const alertController = /*@__PURE__*/ createController(defineCustomElement$1g, alertController$1);
2208
- const actionSheetController = /*@__PURE__*/ createController(defineCustomElement$1f, actionSheetController$1);
2209
- const loadingController = /*@__PURE__*/ createController(defineCustomElement$1h, loadingController$1);
2299
+ const modalController = /*@__PURE__*/ createController(defineCustomElement$1m, modalController$1, true);
2300
+ const popoverController = /*@__PURE__*/ createController(defineCustomElement$1n, popoverController$1, true);
2301
+ const alertController = /*@__PURE__*/ createController(defineCustomElement$1i, alertController$1);
2302
+ const actionSheetController = /*@__PURE__*/ createController(defineCustomElement$1h, actionSheetController$1);
2303
+ const loadingController = /*@__PURE__*/ createController(defineCustomElement$1j, loadingController$1);
2210
2304
  /**
2211
2305
  * @deprecated Use the inline ion-picker component instead.
2212
2306
  */
2213
- const pickerController = /*@__PURE__*/ createController(defineCustomElement$1i, pickerController$1);
2214
- const toastController = /*@__PURE__*/ createController(defineCustomElement$1j, toastController$1);
2307
+ const pickerController = /*@__PURE__*/ createController(defineCustomElement$1k, pickerController$1);
2308
+ const toastController = /*@__PURE__*/ createController(defineCustomElement$1l, toastController$1);
2215
2309
 
2216
- export { IonAccordion, IonAccordionGroup, IonActionSheet, IonAlert, IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonDatetimeButton, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonInputPasswordToggle, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonLoading, IonMenu, IonMenuButton, IonMenuToggle, IonModal, IonNav, IonNavLink, IonNote, IonPage, IonPicker, IonPickerColumn, IonPickerColumnOption, IonPickerLegacy, IonPopover, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRouterOutlet, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSpinner, IonSplitPane, IonTabBar, IonTabButton, IonTabs, IonText, IonTextarea, IonThumbnail, IonTitle, IonToast, IonToggle, IonToolbar, IonicVue, actionSheetController, alertController, loadingController, modalController, onIonViewDidEnter, onIonViewDidLeave, onIonViewWillEnter, onIonViewWillLeave, pickerController, popoverController, toastController, useBackButton, useIonRouter, useKeyboard };
2310
+ export { IonAccordion, IonAccordionGroup, IonActionSheet, IonAlert, IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonDatetimeButton, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonInputPasswordToggle, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonLoading, IonMenu, IonMenuButton, IonMenuToggle, IonModal, IonNav, IonNavLink, IonNote, IonPage, IonPicker, IonPickerColumn, IonPickerColumnOption, IonPickerLegacy, IonPopover, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRouterOutlet, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSpinner, IonSplitPane, IonTab, IonTabBar, IonTabButton, IonTabs, IonText, IonTextarea, IonThumbnail, IonTitle, IonToast, IonToggle, IonToolbar, IonicVue, actionSheetController, alertController, loadingController, modalController, onIonViewDidEnter, onIonViewDidLeave, onIonViewWillEnter, onIonViewWillLeave, pickerController, popoverController, toastController, useBackButton, useIonRouter, useKeyboard };
2217
2311
  //# sourceMappingURL=index.js.map