@ionic/react 8.2.8 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ import { IonMenuButton as IonMenuButton$1, defineCustomElement as defineCustomEl
39
39
  import { IonMenuToggle as IonMenuToggle$1, defineCustomElement as defineCustomElement$B } from '@ionic/core/components/ion-menu-toggle.js';
40
40
  import { IonMenu as IonMenu$1, defineCustomElement as defineCustomElement$z } from '@ionic/core/components/ion-menu.js';
41
41
  import { IonNavLink as IonNavLink$1, defineCustomElement as defineCustomElement$C } from '@ionic/core/components/ion-nav-link.js';
42
- import { defineCustomElement as defineCustomElement$1h } from '@ionic/core/components/ion-nav.js';
42
+ import { defineCustomElement as defineCustomElement$1i } from '@ionic/core/components/ion-nav.js';
43
43
  import { IonNote as IonNote$1, defineCustomElement as defineCustomElement$D } from '@ionic/core/components/ion-note.js';
44
44
  import { IonPickerColumnOption as IonPickerColumnOption$1, defineCustomElement as defineCustomElement$G } from '@ionic/core/components/ion-picker-column-option.js';
45
45
  import { IonPickerColumn as IonPickerColumn$1, defineCustomElement as defineCustomElement$F } from '@ionic/core/components/ion-picker-column.js';
@@ -86,11 +86,12 @@ import { defineCustomElement as defineCustomElement$18 } from '@ionic/core/compo
86
86
  import { defineCustomElement as defineCustomElement$19 } from '@ionic/core/components/ion-modal.js';
87
87
  import { defineCustomElement as defineCustomElement$1a } from '@ionic/core/components/ion-popover.js';
88
88
  import ReactDOM, { createPortal } from 'react-dom';
89
- import { defineCustomElement as defineCustomElement$1g } from '@ionic/core/components/ion-app.js';
90
- import { defineCustomElement as defineCustomElement$1f } from '@ionic/core/components/ion-back-button.js';
89
+ import { defineCustomElement as defineCustomElement$1h } from '@ionic/core/components/ion-app.js';
90
+ import { defineCustomElement as defineCustomElement$1g } from '@ionic/core/components/ion-back-button.js';
91
91
  import { defineCustomElement as defineCustomElement$1c } from '@ionic/core/components/ion-router-outlet.js';
92
92
  import { defineCustomElement as defineCustomElement$1b } from '@ionic/core/components/ion-tab-bar.js';
93
93
  import { defineCustomElement as defineCustomElement$1e } from '@ionic/core/components/ion-tab-button.js';
94
+ import { defineCustomElement as defineCustomElement$1f } from '@ionic/core/components/ion-tabs.js';
94
95
  import { defineCustomElement as defineCustomElement$1d } from 'ionicons/components/ion-icon.js';
95
96
 
96
97
  const IonLifeCycleContext = /*@__PURE__*/ React.createContext({
@@ -1541,9 +1542,10 @@ const createReactComponent = (tagName, ReactComponentContext, manipulatePropsFun
1541
1542
 
1542
1543
  const IonTabButtonInner = /*@__PURE__*/ createReactComponent('ion-tab-button', undefined, undefined, defineCustomElement$1e);
1543
1544
  const IonTabBarInner = /*@__PURE__*/ createReactComponent('ion-tab-bar', undefined, undefined, defineCustomElement$1b);
1544
- const IonBackButtonInner = /*@__PURE__*/ createReactComponent('ion-back-button', undefined, undefined, defineCustomElement$1f);
1545
+ const IonTabsInner = /*@__PURE__*/ createReactComponent('ion-tabs', undefined, undefined, defineCustomElement$1f);
1546
+ const IonBackButtonInner = /*@__PURE__*/ createReactComponent('ion-back-button', undefined, undefined, defineCustomElement$1g);
1545
1547
  const IonRouterOutletInner = /*@__PURE__*/ createReactComponent('ion-router-outlet', undefined, undefined, defineCustomElement$1c);
1546
- const IonAppInner = /*@__PURE__*/ createReactComponent('ion-app', undefined, undefined, defineCustomElement$1g);
1548
+ const IonAppInner = /*@__PURE__*/ createReactComponent('ion-app', undefined, undefined, defineCustomElement$1h);
1547
1549
  // ionicons
1548
1550
  const IonIconInner = /*@__PURE__*/ createReactComponent('ion-icon', undefined, undefined, defineCustomElement$1d);
1549
1551
 
@@ -1706,7 +1708,7 @@ const ReactDelegate = (addView, removeView) => {
1706
1708
  };
1707
1709
  };
1708
1710
 
1709
- const IonNavInner = createReactComponent('ion-nav', undefined, undefined, defineCustomElement$1h);
1711
+ const IonNavInner = createReactComponent('ion-nav', undefined, undefined, defineCustomElement$1i);
1710
1712
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1711
1713
  const IonNavInternal = (_a) => {
1712
1714
  var { children, forwardedRef } = _a, restOfProps = __rest(_a, ["children", "forwardedRef"]);
@@ -1961,9 +1963,15 @@ class IonTabBarUnwrapped extends React.PureComponent {
1961
1963
  };
1962
1964
  }
1963
1965
  onTabButtonClick(e, onClickFn) {
1966
+ var _a;
1964
1967
  const tappedTab = this.state.tabs[e.detail.tab];
1965
1968
  const originalHref = tappedTab.originalHref;
1966
- const currentHref = e.detail.href;
1969
+ /**
1970
+ * If the router outlet is not defined, then the tabs is being used
1971
+ * as a basic tab navigation without the router. In this case, we
1972
+ * don't want to update the href else the URL will change.
1973
+ */
1974
+ const currentHref = ((_a = this.props.routerOutletRef) === null || _a === void 0 ? void 0 : _a.current) ? e.detail.href : '';
1967
1975
  const { activeTab: prevActiveTab } = this.state;
1968
1976
  if (onClickFn) {
1969
1977
  /**
@@ -2077,23 +2085,36 @@ const IonTabs = /*@__PURE__*/ (() => class extends React.Component {
2077
2085
  render() {
2078
2086
  let outlet;
2079
2087
  let tabBar;
2088
+ // Check if IonTabs has any IonTab children
2089
+ let hasTab = false;
2080
2090
  const _a = this.props, { className, onIonTabsDidChange, onIonTabsWillChange } = _a, props = __rest(_a, ["className", "onIonTabsDidChange", "onIonTabsWillChange"]);
2081
2091
  const children = typeof this.props.children === 'function'
2082
2092
  ? this.props.children(this.ionTabContextState)
2083
2093
  : this.props.children;
2094
+ const outletProps = {
2095
+ ref: this.routerOutletRef,
2096
+ };
2084
2097
  React.Children.forEach(children, (child) => {
2085
2098
  // eslint-disable-next-line no-prototype-builtins
2086
2099
  if (child == null || typeof child !== 'object' || !child.hasOwnProperty('type')) {
2087
2100
  return;
2088
2101
  }
2089
2102
  if (child.type === IonRouterOutlet || child.type.isRouterOutlet) {
2090
- outlet = React.cloneElement(child);
2103
+ outlet = React.cloneElement(child, outletProps);
2091
2104
  }
2092
2105
  else if (child.type === Fragment && child.props.children[0].type === IonRouterOutlet) {
2093
- outlet = child.props.children[0];
2106
+ outlet = React.cloneElement(child.props.children[0], outletProps);
2107
+ }
2108
+ else if (child.type === IonTab) {
2109
+ /**
2110
+ * This indicates that IonTabs will be using a basic tab-based navigation
2111
+ * without the history stack or URL updates associated with the router.
2112
+ */
2113
+ hasTab = true;
2094
2114
  }
2095
2115
  let childProps = {
2096
2116
  ref: this.tabBarRef,
2117
+ routerOutletRef: this.routerOutletRef,
2097
2118
  };
2098
2119
  /**
2099
2120
  * Only pass these props
@@ -2116,17 +2137,56 @@ const IonTabs = /*@__PURE__*/ (() => class extends React.Component {
2116
2137
  tabBar = React.cloneElement(child.props.children[1], childProps);
2117
2138
  }
2118
2139
  });
2119
- if (!outlet) {
2120
- throw new Error('IonTabs must contain an IonRouterOutlet');
2140
+ if (!outlet && !hasTab) {
2141
+ throw new Error('IonTabs must contain an IonRouterOutlet or an IonTab');
2142
+ }
2143
+ if (outlet && hasTab) {
2144
+ throw new Error('IonTabs cannot contain an IonRouterOutlet and an IonTab at the same time');
2121
2145
  }
2122
2146
  if (!tabBar) {
2123
2147
  throw new Error('IonTabs needs a IonTabBar');
2124
2148
  }
2149
+ if (hasTab) {
2150
+ return React.createElement(IonTabsInner, Object.assign({}, this.props));
2151
+ }
2152
+ /**
2153
+ * TODO(ROU-11051)
2154
+ *
2155
+ * There is no error handling for the case where there
2156
+ * is no associated Route for the given IonTabButton.
2157
+ *
2158
+ * More investigation is needed to determine how to
2159
+ * handle this to prevent any overwriting of the
2160
+ * IonTabButton's onClick handler and how the routing
2161
+ * is handled.
2162
+ */
2125
2163
  return (React.createElement(IonTabsContext.Provider, { value: this.ionTabContextState }, this.context.hasIonicRouter() ? (React.createElement(PageManager, Object.assign({ className: className ? `${className}` : '', routeInfo: this.context.routeInfo }, props),
2126
- React.createElement("ion-tabs", { className: "ion-tabs", style: hostStyles },
2127
- tabBar.props.slot === 'top' ? tabBar : null,
2128
- React.createElement("div", { style: tabsInner, className: "tabs-inner" }, outlet),
2129
- tabBar.props.slot === 'bottom' ? tabBar : null))) : (React.createElement("div", Object.assign({ className: className ? `${className}` : 'ion-tabs' }, props, { style: hostStyles }),
2164
+ React.createElement(IonTabsInner, Object.assign({}, this.props), React.Children.map(children, (child) => {
2165
+ if (React.isValidElement(child)) {
2166
+ const isTabBar = child.type === IonTabBar ||
2167
+ child.type.isTabBar ||
2168
+ (child.type === Fragment &&
2169
+ (child.props.children[1].type === IonTabBar || child.props.children[1].type.isTabBar));
2170
+ const isRouterOutlet = child.type === IonRouterOutlet ||
2171
+ child.type.isRouterOutlet ||
2172
+ (child.type === Fragment && child.props.children[0].type === IonRouterOutlet);
2173
+ if (isTabBar) {
2174
+ /**
2175
+ * The modified tabBar needs to be returned to include
2176
+ * the context and the overridden methods.
2177
+ */
2178
+ return tabBar;
2179
+ }
2180
+ if (isRouterOutlet) {
2181
+ /**
2182
+ * The modified outlet needs to be returned to include
2183
+ * the ref.
2184
+ */
2185
+ return outlet;
2186
+ }
2187
+ }
2188
+ return child;
2189
+ })))) : (React.createElement("div", Object.assign({ className: className ? `${className}` : 'ion-tabs' }, props, { style: hostStyles }),
2130
2190
  tabBar.props.slot === 'top' ? tabBar : null,
2131
2191
  React.createElement("div", { style: tabsInner, className: "tabs-inner" }, outlet),
2132
2192
  tabBar.props.slot === 'bottom' ? tabBar : null))));