@ionic/vue 8.2.8 → 8.3.1-dev.11725619573.1107b613

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/bundle.ionic.css +1 -0
  9. package/css/ionic/bundle.ionic.css.map +1 -0
  10. package/css/ionic/core.ionic.css +1 -0
  11. package/css/ionic/core.ionic.css.map +1 -0
  12. package/css/ionic/global.bundle.ionic.css +1 -0
  13. package/css/ionic/global.bundle.ionic.css.map +1 -0
  14. package/css/ionic/ionic-swiper.ionic.css +1 -0
  15. package/css/ionic/ionic-swiper.ionic.css.map +1 -0
  16. package/css/ionic/link.ionic.css +1 -0
  17. package/css/ionic/link.ionic.css.map +1 -0
  18. package/css/ionic/structure.ionic.css +1 -0
  19. package/css/ionic/structure.ionic.css.map +1 -0
  20. package/css/ionic/typography.ionic.css +1 -0
  21. package/css/ionic/typography.ionic.css.map +1 -0
  22. package/css/ionic/utils.bundle.ionic.css +1 -0
  23. package/css/ionic/utils.bundle.ionic.css.map +1 -0
  24. package/css/ionic-swiper.css +1 -1
  25. package/css/ionic-swiper.css.map +1 -1
  26. package/css/ionic.bundle.css +1 -1
  27. package/css/ionic.bundle.css.map +1 -1
  28. package/css/normalize.css.map +1 -1
  29. package/css/padding.css.map +1 -1
  30. package/css/palettes/dark.always.css.map +1 -1
  31. package/css/palettes/dark.class.css.map +1 -1
  32. package/css/palettes/dark.system.css.map +1 -1
  33. package/css/palettes/high-contrast-dark.always.css.map +1 -1
  34. package/css/palettes/high-contrast-dark.class.css.map +1 -1
  35. package/css/palettes/high-contrast-dark.system.css.map +1 -1
  36. package/css/palettes/high-contrast.always.css.map +1 -1
  37. package/css/palettes/high-contrast.class.css.map +1 -1
  38. package/css/palettes/high-contrast.system.css.map +1 -1
  39. package/css/structure.css +1 -1
  40. package/css/structure.css.map +1 -1
  41. package/css/text-alignment.css.map +1 -1
  42. package/css/text-transformation.css.map +1 -1
  43. package/css/typography.css +1 -1
  44. package/css/typography.css.map +1 -1
  45. package/css/utils.bundle.css.map +1 -1
  46. package/dist/index.js +226 -100
  47. package/dist/index.js.map +1 -1
  48. package/dist/types/components/IonTabBar.d.ts +29 -0
  49. package/dist/types/components/IonTabButton.d.ts +8 -0
  50. package/dist/types/components/IonTabs.d.ts +10 -1
  51. package/dist/types/components/Overlays.d.ts +1 -1
  52. package/dist/types/proxies.d.ts +1 -0
  53. package/dist/vetur/attributes.json +1349 -111
  54. package/dist/vetur/tags.json +193 -45
  55. package/dist/web-types.json +1298 -129
  56. package/package.json +2 -2
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,7 +299,10 @@ 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);
302
+ const IonAvatar = /*@__PURE__*/ defineContainer('ion-avatar', defineCustomElement$2, [
303
+ 'size',
304
+ 'shape'
305
+ ]);
301
306
  const IonBackdrop = /*@__PURE__*/ defineContainer('ion-backdrop', defineCustomElement$3, [
302
307
  'visible',
303
308
  'tappable',
@@ -305,7 +310,9 @@ const IonBackdrop = /*@__PURE__*/ defineContainer('ion-backdrop', defineCustomEl
305
310
  'ionBackdropTap'
306
311
  ]);
307
312
  const IonBadge = /*@__PURE__*/ defineContainer('ion-badge', defineCustomElement$4, [
308
- 'color'
313
+ 'color',
314
+ 'shape',
315
+ 'size'
309
316
  ]);
310
317
  const IonBreadcrumb = /*@__PURE__*/ defineContainer('ion-breadcrumb', defineCustomElement$5, [
311
318
  'collapsed',
@@ -365,6 +372,7 @@ const IonCard = /*@__PURE__*/ defineContainer('ion-card', defineCustomElement$9,
365
372
  'rel',
366
373
  'routerDirection',
367
374
  'routerAnimation',
375
+ 'shape',
368
376
  'target'
369
377
  ]);
370
378
  const IonCardContent = /*@__PURE__*/ defineContainer('ion-card-content', defineCustomElement$a);
@@ -388,6 +396,8 @@ const IonCheckbox = /*@__PURE__*/ defineContainer('ion-checkbox', defineCustomEl
388
396
  'labelPlacement',
389
397
  'justify',
390
398
  'alignment',
399
+ 'size',
400
+ 'shape',
391
401
  'ionChange',
392
402
  'ionFocus',
393
403
  'ionBlur'
@@ -395,7 +405,9 @@ const IonCheckbox = /*@__PURE__*/ defineContainer('ion-checkbox', defineCustomEl
395
405
  const IonChip = /*@__PURE__*/ defineContainer('ion-chip', defineCustomElement$f, [
396
406
  'color',
397
407
  'outline',
398
- 'disabled'
408
+ 'disabled',
409
+ 'shape',
410
+ 'size'
399
411
  ]);
400
412
  const IonCol = /*@__PURE__*/ defineContainer('ion-col', defineCustomElement$g, [
401
413
  'offset',
@@ -516,6 +528,7 @@ const IonGrid = /*@__PURE__*/ defineContainer('ion-grid', defineCustomElement$o,
516
528
  ]);
517
529
  const IonHeader = /*@__PURE__*/ defineContainer('ion-header', defineCustomElement$p, [
518
530
  'collapse',
531
+ 'divider',
519
532
  'translucent'
520
533
  ]);
521
534
  const IonImg = /*@__PURE__*/ defineContainer('ion-img', defineCustomElement$q, [
@@ -568,6 +581,7 @@ const IonInput = /*@__PURE__*/ defineContainer('ion-input', defineCustomElement$
568
581
  'shape',
569
582
  'spellcheck',
570
583
  'step',
584
+ 'size',
571
585
  'type',
572
586
  'value',
573
587
  'ionInput',
@@ -609,7 +623,8 @@ const IonItemOption = /*@__PURE__*/ defineContainer('ion-item-option', defineCus
609
623
  'href',
610
624
  'rel',
611
625
  'target',
612
- 'type'
626
+ 'type',
627
+ 'shape'
613
628
  ]);
614
629
  const IonItemOptions = /*@__PURE__*/ defineContainer('ion-item-options', defineCustomElement$z, [
615
630
  'side',
@@ -627,7 +642,8 @@ const IonLabel = /*@__PURE__*/ defineContainer('ion-label', defineCustomElement$
627
642
  ]);
628
643
  const IonList = /*@__PURE__*/ defineContainer('ion-list', defineCustomElement$C, [
629
644
  'lines',
630
- 'inset'
645
+ 'inset',
646
+ 'shape'
631
647
  ]);
632
648
  const IonListHeader = /*@__PURE__*/ defineContainer('ion-list-header', defineCustomElement$D, [
633
649
  'color',
@@ -845,7 +861,8 @@ const IonSpinner = /*@__PURE__*/ defineContainer('ion-spinner', defineCustomElem
845
861
  'color',
846
862
  'duration',
847
863
  'name',
848
- 'paused'
864
+ 'paused',
865
+ 'size'
849
866
  ]);
850
867
  const IonSplitPane = /*@__PURE__*/ defineContainer('ion-split-pane', defineCustomElement$11, [
851
868
  'contentId',
@@ -853,10 +870,16 @@ const IonSplitPane = /*@__PURE__*/ defineContainer('ion-split-pane', defineCusto
853
870
  'when',
854
871
  'ionSplitPaneVisible'
855
872
  ]);
856
- const IonText = /*@__PURE__*/ defineContainer('ion-text', defineCustomElement$12, [
873
+ const IonTab = /*@__PURE__*/ defineContainer('ion-tab', defineCustomElement$12, [
874
+ 'active',
875
+ 'delegate',
876
+ 'tab',
877
+ 'component'
878
+ ]);
879
+ const IonText = /*@__PURE__*/ defineContainer('ion-text', defineCustomElement$13, [
857
880
  'color'
858
881
  ]);
859
- const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomElement$13, [
882
+ const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomElement$14, [
860
883
  'color',
861
884
  'autocapitalize',
862
885
  'autofocus',
@@ -885,18 +908,19 @@ const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', defineCustomEl
885
908
  'label',
886
909
  'labelPlacement',
887
910
  'shape',
911
+ 'size',
888
912
  'ionChange',
889
913
  'ionInput',
890
914
  'ionBlur',
891
915
  'ionFocus'
892
916
  ], 'value', 'ion-input');
893
- const IonThumbnail = /*@__PURE__*/ defineContainer('ion-thumbnail', defineCustomElement$14);
894
- const IonTitle = /*@__PURE__*/ defineContainer('ion-title', defineCustomElement$15, [
917
+ const IonThumbnail = /*@__PURE__*/ defineContainer('ion-thumbnail', defineCustomElement$15);
918
+ const IonTitle = /*@__PURE__*/ defineContainer('ion-title', defineCustomElement$16, [
895
919
  'color',
896
920
  'size',
897
921
  'ionStyle'
898
922
  ]);
899
- const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElement$16, [
923
+ const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElement$17, [
900
924
  'color',
901
925
  'name',
902
926
  'checked',
@@ -910,7 +934,7 @@ const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', defineCustomElemen
910
934
  'ionFocus',
911
935
  'ionBlur'
912
936
  ], 'checked', 'ion-change');
913
- const IonToolbar = /*@__PURE__*/ defineContainer('ion-toolbar', defineCustomElement$17, [
937
+ const IonToolbar = /*@__PURE__*/ defineContainer('ion-toolbar', defineCustomElement$18, [
914
938
  'color'
915
939
  ]);
916
940
 
@@ -1088,7 +1112,7 @@ const IonicVue = {
1088
1112
  };
1089
1113
 
1090
1114
  const IonBackButton = /*@__PURE__*/ defineComponent((_, { attrs, slots }) => {
1091
- defineCustomElement$18();
1115
+ defineCustomElement$19();
1092
1116
  // TODO(FW-2969): type
1093
1117
  const ionRouter = inject("navManager");
1094
1118
  const onClick = () => {
@@ -1134,7 +1158,7 @@ const viewDepthKey = Symbol(0);
1134
1158
  const IonRouterOutlet = /*@__PURE__*/ defineComponent({
1135
1159
  name: "IonRouterOutlet",
1136
1160
  setup() {
1137
- defineCustomElement$19();
1161
+ defineCustomElement$1a();
1138
1162
  const injectedRoute = inject(routeLocationKey);
1139
1163
  const route = useRoute();
1140
1164
  const depth = inject(viewDepthKey, 0);
@@ -1568,9 +1592,13 @@ const IonTabButton = /*@__PURE__*/ defineComponent({
1568
1592
  selected: Boolean,
1569
1593
  tab: String,
1570
1594
  target: String,
1595
+ _onClick: {
1596
+ type: Function,
1597
+ required: false,
1598
+ },
1571
1599
  },
1572
1600
  setup(props, { slots }) {
1573
- defineCustomElement$1a();
1601
+ defineCustomElement$1b();
1574
1602
  // TODO(FW-2969): type
1575
1603
  const ionRouter = inject("navManager");
1576
1604
  const onClick = (ev) => {
@@ -1585,10 +1613,25 @@ const IonTabButton = /*@__PURE__*/ defineComponent({
1585
1613
  */
1586
1614
  const { tab, href, _getTabState } = props;
1587
1615
  const tabState = _getTabState();
1616
+ const hasRouterOutlet = tabState.hasRouterOutlet;
1588
1617
  const tappedTab = tabState.tabs[tab] || {};
1589
1618
  const originalHref = tappedTab.originalHref || href;
1590
- const currentHref = tappedTab.currentHref || href;
1619
+ /**
1620
+ * If the router outlet is not defined, then the tabs is being used
1621
+ * as a basic tab navigation without the router. In this case, we
1622
+ * don't want to update the href else the URL will change.
1623
+ */
1624
+ const currentHref = hasRouterOutlet ? tappedTab.currentHref || href : "";
1591
1625
  const prevActiveTab = tabState.activeTab;
1626
+ if (!hasRouterOutlet && props._onClick) {
1627
+ props._onClick(new CustomEvent("ionTabButtonClick", {
1628
+ detail: {
1629
+ href: currentHref,
1630
+ selected: tab === prevActiveTab,
1631
+ tab,
1632
+ },
1633
+ }));
1634
+ }
1592
1635
  /**
1593
1636
  * If we are still on the same
1594
1637
  * tab as before, but the base href
@@ -1631,47 +1674,67 @@ const isTabBar = (node) => {
1631
1674
  return (node.type &&
1632
1675
  (node.type.name === "IonTabBar" || node.type === "ion-tab-bar"));
1633
1676
  };
1677
+ const isTab = (node) => {
1678
+ // The `ion-tab` component was created with the `v-for` directive.
1679
+ if (node.type === Fragment) {
1680
+ if (Array.isArray(node.children)) {
1681
+ return node.children.some((child) => isVNode(child) && isTab(child));
1682
+ }
1683
+ return false; // In case the fragment has no children.
1684
+ }
1685
+ return (node.type && (node.type.name === "ion-tab" || node.type === IonTab));
1686
+ };
1634
1687
  const IonTabs = /*@__PURE__*/ defineComponent({
1635
1688
  name: "IonTabs",
1636
1689
  emits: [WILL_CHANGE, DID_CHANGE],
1690
+ setup(props, { slots, emit }) {
1691
+ return {
1692
+ props,
1693
+ slots,
1694
+ emit,
1695
+ };
1696
+ },
1697
+ mounted() {
1698
+ /**
1699
+ * `defineCustomElement` must be called in the `mounted` hook
1700
+ * to ensure that the custom element is defined after the
1701
+ * component has been fully rendered and initialized.
1702
+ * This prevents issues with undefined properties, like
1703
+ * `selectedTab` from core, which may occur if the custom
1704
+ * element is defined too early in the component's lifecycle.
1705
+ */
1706
+ defineCustomElement$1c();
1707
+ },
1637
1708
  render() {
1638
- var _a;
1639
- const { $slots: slots, $emit } = this;
1709
+ const { slots, emit, props } = this;
1640
1710
  const slottedContent = slots.default && slots.default();
1641
1711
  let routerOutlet;
1642
- /**
1643
- * Developers must pass an ion-router-outlet
1644
- * inside of ion-tabs.
1645
- */
1712
+ let hasTab = false;
1646
1713
  if (slottedContent && slottedContent.length > 0) {
1714
+ /**
1715
+ * Developers must pass an ion-router-outlet
1716
+ * inside of ion-tabs if they want to use
1717
+ * the history stack or URL updates associated
1718
+ * wit the router.
1719
+ */
1647
1720
  routerOutlet = slottedContent.find((child) => isRouterOutlet(child));
1721
+ /**
1722
+ * Developers must pass at least one ion-tab
1723
+ * inside of ion-tabs if they want to use a
1724
+ * basic tab-based navigation without the
1725
+ * history stack or URL updates associated
1726
+ * with the router.
1727
+ */
1728
+ hasTab = slottedContent.some((child) => isTab(child));
1648
1729
  }
1649
- if (!routerOutlet) {
1650
- throw new Error("IonTabs must contain an IonRouterOutlet. See https://ionicframework.com/docs/vue/navigation#working-with-tabs for more information.");
1730
+ if (!routerOutlet && !hasTab) {
1731
+ throw new Error("IonTabs must contain an IonRouterOutlet or an IonTab.");
1732
+ }
1733
+ if (routerOutlet && hasTab) {
1734
+ throw new Error("IonTabs cannot contain an IonRouterOutlet and IonTab at the same time.");
1651
1735
  }
1652
- let childrenToRender = [
1653
- h("div", {
1654
- class: "tabs-inner",
1655
- style: {
1656
- position: "relative",
1657
- flex: "1",
1658
- contain: "layout size style",
1659
- },
1660
- }, routerOutlet),
1661
- ];
1662
- /**
1663
- * If ion-tab-bar has slot="top" it needs to be
1664
- * rendered before `.tabs-inner` otherwise it will
1665
- * not show above the tab content.
1666
- */
1667
1736
  if (slottedContent && slottedContent.length > 0) {
1668
- /**
1669
- * Render all content except for router outlet
1670
- * since that needs to be inside of `.tabs-inner`.
1671
- */
1672
- const filteredContent = slottedContent.filter((child) => !child.type || !isRouterOutlet(child));
1673
- const slottedTabBar = filteredContent.find((child) => isTabBar(child));
1674
- const hasTopSlotTabBar = slottedTabBar && ((_a = slottedTabBar.props) === null || _a === void 0 ? void 0 : _a.slot) === "top";
1737
+ const slottedTabBar = slottedContent.find((child) => isTabBar(child));
1675
1738
  if (slottedTabBar) {
1676
1739
  if (!slottedTabBar.props) {
1677
1740
  slottedTabBar.props = {};
@@ -1683,16 +1746,24 @@ const IonTabs = /*@__PURE__*/ defineComponent({
1683
1746
  * TODO: We may want to move logic from the tab bar into here
1684
1747
  * so we do not have code split across two components.
1685
1748
  */
1686
- slottedTabBar.props._tabsWillChange = (tab) => $emit(WILL_CHANGE, { tab });
1687
- slottedTabBar.props._tabsDidChange = (tab) => $emit(DID_CHANGE, { tab });
1688
- }
1689
- if (hasTopSlotTabBar) {
1690
- childrenToRender = [...filteredContent, ...childrenToRender];
1691
- }
1692
- else {
1693
- childrenToRender = [...childrenToRender, ...filteredContent];
1749
+ slottedTabBar.props._tabsWillChange = (tab) => emit(WILL_CHANGE, { tab });
1750
+ slottedTabBar.props._tabsDidChange = (tab) => emit(DID_CHANGE, { tab });
1751
+ slottedTabBar.props._hasRouterOutlet = !!routerOutlet;
1694
1752
  }
1695
1753
  }
1754
+ if (hasTab) {
1755
+ return h("ion-tabs", Object.assign({}, props), slottedContent);
1756
+ }
1757
+ /**
1758
+ * TODO(ROU-11056)
1759
+ *
1760
+ * Vue handles the error case for when there is no
1761
+ * associated page matching the tab `href`.
1762
+ *
1763
+ * More investigation is needed to determine if we
1764
+ * override the error handling and provide our own
1765
+ * error message.
1766
+ */
1696
1767
  return h("ion-tabs", {
1697
1768
  style: {
1698
1769
  display: "flex",
@@ -1707,7 +1778,7 @@ const IonTabs = /*@__PURE__*/ defineComponent({
1707
1778
  contain: "layout size style",
1708
1779
  "z-index": "0",
1709
1780
  },
1710
- }, childrenToRender);
1781
+ }, slottedContent);
1711
1782
  },
1712
1783
  });
1713
1784
 
@@ -1731,6 +1802,7 @@ const IonTabBar = defineComponent({
1731
1802
  /* eslint-disable @typescript-eslint/no-empty-function */
1732
1803
  _tabsWillChange: { type: Function, default: () => { } },
1733
1804
  _tabsDidChange: { type: Function, default: () => { } },
1805
+ _hasRouterOutlet: { type: Boolean, default: false },
1734
1806
  /* eslint-enable @typescript-eslint/no-empty-function */
1735
1807
  },
1736
1808
  data() {
@@ -1747,6 +1819,7 @@ const IonTabBar = defineComponent({
1747
1819
  },
1748
1820
  methods: {
1749
1821
  setupTabState(ionRouter) {
1822
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1750
1823
  /**
1751
1824
  * For each tab, we need to keep track of its
1752
1825
  * base href as well as any child page that
@@ -1763,25 +1836,65 @@ const IonTabBar = defineComponent({
1763
1836
  currentHref: child.props.href,
1764
1837
  ref: child,
1765
1838
  };
1839
+ /**
1840
+ * Passing this prop to each tab button
1841
+ * lets it be aware of the presence of
1842
+ * the router outlet.
1843
+ */
1844
+ tabState.hasRouterOutlet = hasRouterOutlet;
1766
1845
  /**
1767
1846
  * Passing this prop to each tab button
1768
1847
  * lets it be aware of the state that
1769
1848
  * ion-tab-bar is managing for it.
1770
1849
  */
1771
1850
  child.component.props._getTabState = () => tabState;
1851
+ /**
1852
+ * If the router outlet is not defined, then the tabs are being used
1853
+ * as a basic tab navigation without the router. In this case, the
1854
+ * tabs will not emit the `ionTabsDidChange` and `ionTabsWillChange`
1855
+ * events through the `checkActiveTab` method. Instead, we need to
1856
+ * handle those events through the tab buttons.
1857
+ */
1858
+ if (!hasRouterOutlet) {
1859
+ child.component.props._onClick = (event) => {
1860
+ this.handleIonTabButtonClick(event);
1861
+ };
1862
+ }
1772
1863
  });
1773
1864
  this.checkActiveTab(ionRouter);
1774
1865
  },
1866
+ /**
1867
+ * This method is called upon setup and when the
1868
+ * history changes. It checks the current route
1869
+ * and updates the active tab accordingly.
1870
+ *
1871
+ * History changes only occur when the router
1872
+ * outlet is present. Due to this, the
1873
+ * `ionTabsDidChange` and `ionTabsWillChange`
1874
+ * events are only emitted when the router
1875
+ * outlet is present. A different approach must
1876
+ * be taken for tabs without a router outlet.
1877
+ *
1878
+ * @param ionRouter
1879
+ */
1775
1880
  checkActiveTab(ionRouter) {
1881
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1776
1882
  const currentRoute = ionRouter.getCurrentRouteInfo();
1777
1883
  const childNodes = this.$data.tabVnodes;
1778
1884
  const { tabs, activeTab: prevActiveTab } = this.$data.tabState;
1779
- const tabState = this.$data.tabState;
1780
1885
  const tabKeys = Object.keys(tabs);
1781
- const activeTab = tabKeys.find((key) => {
1886
+ let activeTab = tabKeys.find((key) => {
1782
1887
  const href = tabs[key].originalHref;
1783
1888
  return currentRoute.pathname.startsWith(href);
1784
1889
  });
1890
+ /**
1891
+ * Tabs is being used as a basic tab navigation,
1892
+ * so we need to set the first tab as active since
1893
+ * `checkActiveTab` will not be called after setup.
1894
+ */
1895
+ if (!activeTab && !hasRouterOutlet) {
1896
+ activeTab = tabKeys[0];
1897
+ }
1785
1898
  /**
1786
1899
  * For each tab, check to see if the
1787
1900
  * base href has changed. If so, update
@@ -1825,23 +1938,36 @@ const IonTabBar = defineComponent({
1825
1938
  tabs[prevActiveTab] = Object.assign(Object.assign({}, tabs[prevActiveTab]), { currentHref: tabs[prevActiveTab].originalHref });
1826
1939
  }
1827
1940
  }
1941
+ this.tabSwitch(activeTab, ionRouter);
1942
+ },
1943
+ handleIonTabButtonClick(event) {
1944
+ const activeTab = event.detail.tab;
1945
+ this.tabSwitch(activeTab);
1946
+ },
1947
+ tabSwitch(activeTab, ionRouter) {
1948
+ const hasRouterOutlet = this.$props._hasRouterOutlet;
1949
+ const childNodes = this.$data.tabVnodes;
1950
+ const { activeTab: prevActiveTab } = this.$data.tabState;
1951
+ const tabState = this.$data.tabState;
1828
1952
  const activeChild = childNodes.find((child) => { var _a; return isTabButton(child) && ((_a = child.props) === null || _a === void 0 ? void 0 : _a.tab) === activeTab; });
1829
1953
  const tabBar = this.$refs.ionTabBar;
1830
1954
  const tabDidChange = activeTab !== prevActiveTab;
1831
1955
  if (tabBar) {
1832
1956
  if (activeChild) {
1833
1957
  tabDidChange && this.$props._tabsWillChange(activeTab);
1834
- ionRouter.handleSetCurrentTab(activeTab);
1958
+ if (hasRouterOutlet && ionRouter) {
1959
+ ionRouter.handleSetCurrentTab(activeTab);
1960
+ }
1835
1961
  tabBar.selectedTab = tabState.activeTab = activeTab;
1836
1962
  tabDidChange && this.$props._tabsDidChange(activeTab);
1963
+ }
1964
+ else {
1837
1965
  /**
1838
1966
  * When going to a tab that does
1839
1967
  * not have an associated ion-tab-button
1840
1968
  * we need to remove the selected state from
1841
1969
  * the old tab.
1842
1970
  */
1843
- }
1844
- else {
1845
1971
  tabBar.selectedTab = tabState.activeTab = "";
1846
1972
  }
1847
1973
  }
@@ -1853,7 +1979,7 @@ const IonTabBar = defineComponent({
1853
1979
  ionRouter.registerHistoryChangeListener(() => this.checkActiveTab(ionRouter));
1854
1980
  },
1855
1981
  setup(_, { slots }) {
1856
- defineCustomElement$1b();
1982
+ defineCustomElement$1d();
1857
1983
  return () => {
1858
1984
  return h("ion-tab-bar", { ref: "ionTabBar" }, slots.default && slots.default());
1859
1985
  };
@@ -1862,7 +1988,7 @@ const IonTabBar = defineComponent({
1862
1988
 
1863
1989
  const userComponents = shallowRef([]);
1864
1990
  const IonApp = /*@__PURE__*/ defineComponent((_, { attrs, slots }) => {
1865
- defineCustomElement$1c();
1991
+ defineCustomElement$1e();
1866
1992
  return () => {
1867
1993
  return h("ion-app", Object.assign({}, attrs), [slots.default && slots.default(), ...userComponents.value]);
1868
1994
  };
@@ -1914,7 +2040,7 @@ const VueDelegate = (addFn = addTeleportedUserComponent, removeFn = removeTelepo
1914
2040
  };
1915
2041
 
1916
2042
  const IonNav = /*@__PURE__*/ defineComponent((props) => {
1917
- defineCustomElement$1d();
2043
+ defineCustomElement$1f();
1918
2044
  const views = shallowRef([]);
1919
2045
  /**
1920
2046
  * Allows us to create the component
@@ -1974,7 +2100,7 @@ const IonIcon = /*@__PURE__*/ defineComponent({
1974
2100
  src: String,
1975
2101
  },
1976
2102
  setup(props, { slots }) {
1977
- defineCustomElement$1e();
2103
+ defineCustomElement$1g();
1978
2104
  return () => {
1979
2105
  var _a, _b;
1980
2106
  const { icon, ios, md, mode } = props;
@@ -2163,13 +2289,13 @@ const defineOverlayContainer = (name, defineCustomElement, componentProps = [],
2163
2289
  * This is an autogenerated file created by 'scripts/copy-overlays.js'.
2164
2290
  * Changes made to this file will be overwritten on build.
2165
2291
  */
2166
- const IonActionSheet = /*@__PURE__*/ defineOverlayContainer('ion-action-sheet', defineCustomElement$1f, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'translucent', 'trigger']);
2167
- const IonAlert = /*@__PURE__*/ defineOverlayContainer('ion-alert', defineCustomElement$1g, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'translucent', 'trigger']);
2168
- const IonLoading = /*@__PURE__*/ defineOverlayContainer('ion-loading', defineCustomElement$1h, ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'translucent', 'trigger']);
2169
- const IonPickerLegacy = /*@__PURE__*/ defineOverlayContainer('ion-picker-legacy', defineCustomElement$1i, ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger']);
2170
- 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', 'translucent', 'trigger']);
2171
- 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', 'trigger'], true);
2172
- 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', 'translucent', 'trigger', 'triggerAction']);
2292
+ const IonActionSheet = /*@__PURE__*/ defineOverlayContainer('ion-action-sheet', defineCustomElement$1h, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'theme', 'translucent', 'trigger']);
2293
+ const IonAlert = /*@__PURE__*/ defineOverlayContainer('ion-alert', defineCustomElement$1i, ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'theme', 'translucent', 'trigger']);
2294
+ const IonLoading = /*@__PURE__*/ defineOverlayContainer('ion-loading', defineCustomElement$1j, ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'theme', 'translucent', 'trigger']);
2295
+ const IonPickerLegacy = /*@__PURE__*/ defineOverlayContainer('ion-picker-legacy', defineCustomElement$1k, ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'theme', 'trigger']);
2296
+ 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', 'theme', 'translucent', 'trigger']);
2297
+ 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', 'theme', 'trigger'], true);
2298
+ 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', 'theme', 'translucent', 'trigger', 'triggerAction']);
2173
2299
 
2174
2300
  // TODO(FW-2969): types
2175
2301
  /**
@@ -2186,16 +2312,16 @@ const createController = (defineCustomElement, oldController, useDelegate = fals
2186
2312
  };
2187
2313
  return oldController;
2188
2314
  };
2189
- const modalController = /*@__PURE__*/ createController(defineCustomElement$1k, modalController$1, true);
2190
- const popoverController = /*@__PURE__*/ createController(defineCustomElement$1l, popoverController$1, true);
2191
- const alertController = /*@__PURE__*/ createController(defineCustomElement$1g, alertController$1);
2192
- const actionSheetController = /*@__PURE__*/ createController(defineCustomElement$1f, actionSheetController$1);
2193
- const loadingController = /*@__PURE__*/ createController(defineCustomElement$1h, loadingController$1);
2315
+ const modalController = /*@__PURE__*/ createController(defineCustomElement$1m, modalController$1, true);
2316
+ const popoverController = /*@__PURE__*/ createController(defineCustomElement$1n, popoverController$1, true);
2317
+ const alertController = /*@__PURE__*/ createController(defineCustomElement$1i, alertController$1);
2318
+ const actionSheetController = /*@__PURE__*/ createController(defineCustomElement$1h, actionSheetController$1);
2319
+ const loadingController = /*@__PURE__*/ createController(defineCustomElement$1j, loadingController$1);
2194
2320
  /**
2195
2321
  * @deprecated Use the inline ion-picker component instead.
2196
2322
  */
2197
- const pickerController = /*@__PURE__*/ createController(defineCustomElement$1i, pickerController$1);
2198
- const toastController = /*@__PURE__*/ createController(defineCustomElement$1j, toastController$1);
2323
+ const pickerController = /*@__PURE__*/ createController(defineCustomElement$1k, pickerController$1);
2324
+ const toastController = /*@__PURE__*/ createController(defineCustomElement$1l, toastController$1);
2199
2325
 
2200
- 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 };
2326
+ 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 };
2201
2327
  //# sourceMappingURL=index.js.map