@ionic/react 8.3.3-dev.11728581904.17739cf7 → 8.3.3-dev.11728940793.1be4a504
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
|
@@ -1260,8 +1260,6 @@ const IonNav = createForwardRef(IonNavInternal, 'IonNav');
|
|
|
1260
1260
|
const IonTabsContext = React.createContext({
|
|
1261
1261
|
activeTab: undefined,
|
|
1262
1262
|
selectTab: () => false,
|
|
1263
|
-
hasRouterOutlet: false,
|
|
1264
|
-
tabBarProps: { ref: React.createRef() },
|
|
1265
1263
|
});
|
|
1266
1264
|
|
|
1267
1265
|
const HTMLElementSSR = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
|
|
@@ -1349,140 +1347,6 @@ class IonRouterOutletContainer extends React.Component {
|
|
|
1349
1347
|
}
|
|
1350
1348
|
const IonRouterOutlet = createForwardRef(IonRouterOutletContainer, 'IonRouterOutlet');
|
|
1351
1349
|
|
|
1352
|
-
class IonTabsElement extends HTMLElementSSR {
|
|
1353
|
-
constructor() {
|
|
1354
|
-
super();
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
// TODO(FW-2959): types
|
|
1358
|
-
if (typeof window !== 'undefined' && window.customElements) {
|
|
1359
|
-
const element = window.customElements.get('ion-tabs');
|
|
1360
|
-
if (!element) {
|
|
1361
|
-
window.customElements.define('ion-tabs', IonTabsElement);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
const IonTabs = /*@__PURE__*/ (() => class extends React.Component {
|
|
1365
|
-
constructor(props) {
|
|
1366
|
-
super(props);
|
|
1367
|
-
/**
|
|
1368
|
-
* `routerOutletRef` allows users to add a `ref` to `IonRouterOutlet`.
|
|
1369
|
-
* Without this, `ref.current` will be `undefined` in the user's app,
|
|
1370
|
-
* breaking their ability to access the `IonRouterOutlet` instance.
|
|
1371
|
-
* Do not remove this ref.
|
|
1372
|
-
*/
|
|
1373
|
-
this.routerOutletRef = React.createRef();
|
|
1374
|
-
this.tabBarRef = React.createRef();
|
|
1375
|
-
this.ionTabContextState = {
|
|
1376
|
-
activeTab: undefined,
|
|
1377
|
-
selectTab: () => false,
|
|
1378
|
-
hasRouterOutlet: false,
|
|
1379
|
-
/**
|
|
1380
|
-
* Tab bar can be used as a standalone component,
|
|
1381
|
-
* so the props can not be passed directly to the
|
|
1382
|
-
* tab bar component. Instead, props will be
|
|
1383
|
-
* passed through the context.
|
|
1384
|
-
*/
|
|
1385
|
-
tabBarProps: { ref: this.tabBarRef },
|
|
1386
|
-
};
|
|
1387
|
-
}
|
|
1388
|
-
componentDidMount() {
|
|
1389
|
-
if (this.tabBarRef.current) {
|
|
1390
|
-
// Grab initial value
|
|
1391
|
-
this.ionTabContextState.activeTab = this.tabBarRef.current.state.activeTab;
|
|
1392
|
-
// Override method
|
|
1393
|
-
this.tabBarRef.current.setActiveTabOnContext = (tab) => {
|
|
1394
|
-
this.ionTabContextState.activeTab = tab;
|
|
1395
|
-
};
|
|
1396
|
-
this.ionTabContextState.selectTab = this.tabBarRef.current.selectTab;
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
renderTabsInner(children, outlet) {
|
|
1400
|
-
return (React.createElement(IonTabsInner, Object.assign({}, this.props), React.Children.map(children, (child) => {
|
|
1401
|
-
if (React.isValidElement(child)) {
|
|
1402
|
-
const isRouterOutlet = child.type === IonRouterOutlet ||
|
|
1403
|
-
child.type.isRouterOutlet ||
|
|
1404
|
-
(child.type === Fragment && child.props.children[0].type === IonRouterOutlet);
|
|
1405
|
-
if (isRouterOutlet) {
|
|
1406
|
-
/**
|
|
1407
|
-
* The modified outlet needs to be returned to include
|
|
1408
|
-
* the ref.
|
|
1409
|
-
*/
|
|
1410
|
-
return outlet;
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
return child;
|
|
1414
|
-
})));
|
|
1415
|
-
}
|
|
1416
|
-
render() {
|
|
1417
|
-
let outlet;
|
|
1418
|
-
// Check if IonTabs has any IonTab children
|
|
1419
|
-
let hasTab = false;
|
|
1420
|
-
const _a = this.props, { className, onIonTabsDidChange, onIonTabsWillChange } = _a, props = __rest(_a, ["className", "onIonTabsDidChange", "onIonTabsWillChange"]);
|
|
1421
|
-
const children = typeof this.props.children === 'function'
|
|
1422
|
-
? this.props.children(this.ionTabContextState)
|
|
1423
|
-
: this.props.children;
|
|
1424
|
-
React.Children.forEach(children, (child) => {
|
|
1425
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
1426
|
-
if (child == null || typeof child !== 'object' || !child.hasOwnProperty('type')) {
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
if (child.type === IonRouterOutlet || child.type.isRouterOutlet) {
|
|
1430
|
-
outlet = React.cloneElement(child);
|
|
1431
|
-
}
|
|
1432
|
-
else if (child.type === Fragment && child.props.children[0].type === IonRouterOutlet) {
|
|
1433
|
-
outlet = React.cloneElement(child.props.children[0]);
|
|
1434
|
-
}
|
|
1435
|
-
else if (child.type === IonTab) {
|
|
1436
|
-
/**
|
|
1437
|
-
* This indicates that IonTabs will be using a basic tab-based navigation
|
|
1438
|
-
* without the history stack or URL updates associated with the router.
|
|
1439
|
-
*/
|
|
1440
|
-
hasTab = true;
|
|
1441
|
-
}
|
|
1442
|
-
this.ionTabContextState.hasRouterOutlet = !!outlet;
|
|
1443
|
-
let childProps = Object.assign({}, this.ionTabContextState.tabBarProps);
|
|
1444
|
-
/**
|
|
1445
|
-
* Only pass these props
|
|
1446
|
-
* down from IonTabs to IonTabBar
|
|
1447
|
-
* if they are defined, otherwise
|
|
1448
|
-
* if you have a handler set on
|
|
1449
|
-
* IonTabBar it will be overridden.
|
|
1450
|
-
*/
|
|
1451
|
-
if (onIonTabsDidChange !== undefined) {
|
|
1452
|
-
childProps = Object.assign(Object.assign({}, childProps), { onIonTabsDidChange });
|
|
1453
|
-
}
|
|
1454
|
-
if (onIonTabsWillChange !== undefined) {
|
|
1455
|
-
childProps = Object.assign(Object.assign({}, childProps), { onIonTabsWillChange });
|
|
1456
|
-
}
|
|
1457
|
-
this.ionTabContextState.tabBarProps = childProps;
|
|
1458
|
-
});
|
|
1459
|
-
if (!outlet && !hasTab) {
|
|
1460
|
-
throw new Error('IonTabs must contain an IonRouterOutlet or an IonTab');
|
|
1461
|
-
}
|
|
1462
|
-
if (outlet && hasTab) {
|
|
1463
|
-
throw new Error('IonTabs cannot contain an IonRouterOutlet and an IonTab at the same time');
|
|
1464
|
-
}
|
|
1465
|
-
if (hasTab) {
|
|
1466
|
-
return React.createElement(IonTabsInner, Object.assign({}, this.props));
|
|
1467
|
-
}
|
|
1468
|
-
/**
|
|
1469
|
-
* TODO(ROU-11051)
|
|
1470
|
-
*
|
|
1471
|
-
* There is no error handling for the case where there
|
|
1472
|
-
* is no associated Route for the given IonTabButton.
|
|
1473
|
-
*
|
|
1474
|
-
* More investigation is needed to determine how to
|
|
1475
|
-
* handle this to prevent any overwriting of the
|
|
1476
|
-
* IonTabButton's onClick handler and how the routing
|
|
1477
|
-
* is handled.
|
|
1478
|
-
*/
|
|
1479
|
-
return (React.createElement(IonTabsContext.Provider, { value: this.ionTabContextState }, this.context.hasIonicRouter() ? (React.createElement(PageManager, Object.assign({ className: className ? `${className}` : '', routeInfo: this.context.routeInfo }, props), this.renderTabsInner(children, outlet))) : (this.renderTabsInner(children, outlet))));
|
|
1480
|
-
}
|
|
1481
|
-
static get contextType() {
|
|
1482
|
-
return NavContext;
|
|
1483
|
-
}
|
|
1484
|
-
})();
|
|
1485
|
-
|
|
1486
1350
|
const IonTabButton = /*@__PURE__*/ (() => class extends React.Component {
|
|
1487
1351
|
constructor(props) {
|
|
1488
1352
|
super(props);
|
|
@@ -1632,16 +1496,15 @@ class IonTabBarUnwrapped extends React.PureComponent {
|
|
|
1632
1496
|
};
|
|
1633
1497
|
}
|
|
1634
1498
|
onTabButtonClick(e, onClickFn) {
|
|
1635
|
-
var _a;
|
|
1499
|
+
var _a, _b;
|
|
1636
1500
|
const tappedTab = this.state.tabs[e.detail.tab];
|
|
1637
1501
|
const originalHref = tappedTab.originalHref;
|
|
1638
|
-
const hasRouterOutlet = (_a = this.props.tabsContext) === null || _a === void 0 ? void 0 : _a.hasRouterOutlet;
|
|
1639
1502
|
/**
|
|
1640
1503
|
* If the router outlet is not defined, then the tabs is being used
|
|
1641
1504
|
* as a basic tab navigation without the router. In this case, we
|
|
1642
1505
|
* don't want to update the href else the URL will change.
|
|
1643
1506
|
*/
|
|
1644
|
-
const currentHref =
|
|
1507
|
+
const currentHref = ((_a = this.props.routerOutletRef) === null || _a === void 0 ? void 0 : _a.current) ? e.detail.href : '';
|
|
1645
1508
|
const { activeTab: prevActiveTab } = this.state;
|
|
1646
1509
|
if (onClickFn) {
|
|
1647
1510
|
/**
|
|
@@ -1664,7 +1527,7 @@ class IonTabBarUnwrapped extends React.PureComponent {
|
|
|
1664
1527
|
if (this.props.onIonTabsDidChange) {
|
|
1665
1528
|
this.props.onIonTabsDidChange(new CustomEvent('ionTabDidChange', { detail: { tab: e.detail.tab } }));
|
|
1666
1529
|
}
|
|
1667
|
-
if (
|
|
1530
|
+
if ((_b = this.props.routerOutletRef) === null || _b === void 0 ? void 0 : _b.current) {
|
|
1668
1531
|
this.setActiveTabOnContext(e.detail.tab);
|
|
1669
1532
|
this.context.changeTab(e.detail.tab, currentHref, e.detail.routeOptions);
|
|
1670
1533
|
}
|
|
@@ -1700,20 +1563,171 @@ class IonTabBarUnwrapped extends React.PureComponent {
|
|
|
1700
1563
|
const IonTabBarContainer = React.memo((_a) => {
|
|
1701
1564
|
var { forwardedRef } = _a, props = __rest(_a, ["forwardedRef"]);
|
|
1702
1565
|
const context = useContext(NavContext);
|
|
1703
|
-
|
|
1704
|
-
const tabBarRef = forwardedRef || tabsContext.tabBarProps.ref;
|
|
1705
|
-
const updatedTabBarProps = Object.assign(Object.assign({}, tabsContext.tabBarProps), { ref: tabBarRef });
|
|
1706
|
-
return (React.createElement(IonTabBarUnwrapped, Object.assign({ ref: tabBarRef }, props, { routeInfo: props.routeInfo || context.routeInfo || { pathname: window.location.pathname }, onSetCurrentTab: context.setCurrentTab,
|
|
1707
|
-
/**
|
|
1708
|
-
* Tab bar can be used as a standalone component,
|
|
1709
|
-
* so it cannot be modified directly through
|
|
1710
|
-
* IonTabs. Instead, props will be passed through
|
|
1711
|
-
* the context.
|
|
1712
|
-
*/
|
|
1713
|
-
tabsContext: Object.assign(Object.assign({}, tabsContext), { tabBarProps: updatedTabBarProps }) }), props.children));
|
|
1566
|
+
return (React.createElement(IonTabBarUnwrapped, Object.assign({ ref: forwardedRef }, props, { routeInfo: props.routeInfo || context.routeInfo || { pathname: window.location.pathname }, onSetCurrentTab: context.setCurrentTab }), props.children));
|
|
1714
1567
|
});
|
|
1715
1568
|
const IonTabBar = createForwardRef(IonTabBarContainer, 'IonTabBar');
|
|
1716
1569
|
|
|
1570
|
+
class IonTabsElement extends HTMLElementSSR {
|
|
1571
|
+
constructor() {
|
|
1572
|
+
super();
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
// TODO(FW-2959): types
|
|
1576
|
+
if (typeof window !== 'undefined' && window.customElements) {
|
|
1577
|
+
const element = window.customElements.get('ion-tabs');
|
|
1578
|
+
if (!element) {
|
|
1579
|
+
window.customElements.define('ion-tabs', IonTabsElement);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
const hostStyles = {
|
|
1583
|
+
display: 'flex',
|
|
1584
|
+
position: 'absolute',
|
|
1585
|
+
top: '0',
|
|
1586
|
+
left: '0',
|
|
1587
|
+
right: '0',
|
|
1588
|
+
bottom: '0',
|
|
1589
|
+
flexDirection: 'column',
|
|
1590
|
+
width: '100%',
|
|
1591
|
+
height: '100%',
|
|
1592
|
+
contain: 'layout size style',
|
|
1593
|
+
};
|
|
1594
|
+
const tabsInner = {
|
|
1595
|
+
position: 'relative',
|
|
1596
|
+
flex: 1,
|
|
1597
|
+
contain: 'layout size style',
|
|
1598
|
+
};
|
|
1599
|
+
const IonTabs = /*@__PURE__*/ (() => class extends React.Component {
|
|
1600
|
+
constructor(props) {
|
|
1601
|
+
super(props);
|
|
1602
|
+
this.routerOutletRef = React.createRef();
|
|
1603
|
+
this.tabBarRef = React.createRef();
|
|
1604
|
+
this.ionTabContextState = {
|
|
1605
|
+
activeTab: undefined,
|
|
1606
|
+
selectTab: () => false,
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
componentDidMount() {
|
|
1610
|
+
if (this.tabBarRef.current) {
|
|
1611
|
+
// Grab initial value
|
|
1612
|
+
this.ionTabContextState.activeTab = this.tabBarRef.current.state.activeTab;
|
|
1613
|
+
// Override method
|
|
1614
|
+
this.tabBarRef.current.setActiveTabOnContext = (tab) => {
|
|
1615
|
+
this.ionTabContextState.activeTab = tab;
|
|
1616
|
+
};
|
|
1617
|
+
this.ionTabContextState.selectTab = this.tabBarRef.current.selectTab;
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
render() {
|
|
1621
|
+
let outlet;
|
|
1622
|
+
let tabBar;
|
|
1623
|
+
// Check if IonTabs has any IonTab children
|
|
1624
|
+
let hasTab = false;
|
|
1625
|
+
const _a = this.props, { className, onIonTabsDidChange, onIonTabsWillChange } = _a, props = __rest(_a, ["className", "onIonTabsDidChange", "onIonTabsWillChange"]);
|
|
1626
|
+
const children = typeof this.props.children === 'function'
|
|
1627
|
+
? this.props.children(this.ionTabContextState)
|
|
1628
|
+
: this.props.children;
|
|
1629
|
+
const outletProps = {
|
|
1630
|
+
ref: this.routerOutletRef,
|
|
1631
|
+
};
|
|
1632
|
+
React.Children.forEach(children, (child) => {
|
|
1633
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
1634
|
+
if (child == null || typeof child !== 'object' || !child.hasOwnProperty('type')) {
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
if (child.type === IonRouterOutlet || child.type.isRouterOutlet) {
|
|
1638
|
+
outlet = React.cloneElement(child, outletProps);
|
|
1639
|
+
}
|
|
1640
|
+
else if (child.type === Fragment && child.props.children[0].type === IonRouterOutlet) {
|
|
1641
|
+
outlet = React.cloneElement(child.props.children[0], outletProps);
|
|
1642
|
+
}
|
|
1643
|
+
else if (child.type === IonTab) {
|
|
1644
|
+
/**
|
|
1645
|
+
* This indicates that IonTabs will be using a basic tab-based navigation
|
|
1646
|
+
* without the history stack or URL updates associated with the router.
|
|
1647
|
+
*/
|
|
1648
|
+
hasTab = true;
|
|
1649
|
+
}
|
|
1650
|
+
let childProps = {
|
|
1651
|
+
ref: this.tabBarRef,
|
|
1652
|
+
routerOutletRef: this.routerOutletRef,
|
|
1653
|
+
};
|
|
1654
|
+
/**
|
|
1655
|
+
* Only pass these props
|
|
1656
|
+
* down from IonTabs to IonTabBar
|
|
1657
|
+
* if they are defined, otherwise
|
|
1658
|
+
* if you have a handler set on
|
|
1659
|
+
* IonTabBar it will be overridden.
|
|
1660
|
+
*/
|
|
1661
|
+
if (onIonTabsDidChange !== undefined) {
|
|
1662
|
+
childProps = Object.assign(Object.assign({}, childProps), { onIonTabsDidChange });
|
|
1663
|
+
}
|
|
1664
|
+
if (onIonTabsWillChange !== undefined) {
|
|
1665
|
+
childProps = Object.assign(Object.assign({}, childProps), { onIonTabsWillChange });
|
|
1666
|
+
}
|
|
1667
|
+
if (child.type === IonTabBar || child.type.isTabBar) {
|
|
1668
|
+
tabBar = React.cloneElement(child, childProps);
|
|
1669
|
+
}
|
|
1670
|
+
else if (child.type === Fragment &&
|
|
1671
|
+
(child.props.children[1].type === IonTabBar || child.props.children[1].type.isTabBar)) {
|
|
1672
|
+
tabBar = React.cloneElement(child.props.children[1], childProps);
|
|
1673
|
+
}
|
|
1674
|
+
});
|
|
1675
|
+
if (!outlet && !hasTab) {
|
|
1676
|
+
throw new Error('IonTabs must contain an IonRouterOutlet or an IonTab');
|
|
1677
|
+
}
|
|
1678
|
+
if (outlet && hasTab) {
|
|
1679
|
+
throw new Error('IonTabs cannot contain an IonRouterOutlet and an IonTab at the same time');
|
|
1680
|
+
}
|
|
1681
|
+
if (hasTab) {
|
|
1682
|
+
return React.createElement(IonTabsInner, Object.assign({}, this.props));
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* TODO(ROU-11051)
|
|
1686
|
+
*
|
|
1687
|
+
* There is no error handling for the case where there
|
|
1688
|
+
* is no associated Route for the given IonTabButton.
|
|
1689
|
+
*
|
|
1690
|
+
* More investigation is needed to determine how to
|
|
1691
|
+
* handle this to prevent any overwriting of the
|
|
1692
|
+
* IonTabButton's onClick handler and how the routing
|
|
1693
|
+
* is handled.
|
|
1694
|
+
*/
|
|
1695
|
+
return (React.createElement(IonTabsContext.Provider, { value: this.ionTabContextState }, this.context.hasIonicRouter() ? (React.createElement(PageManager, Object.assign({ className: className ? `${className}` : '', routeInfo: this.context.routeInfo }, props),
|
|
1696
|
+
React.createElement(IonTabsInner, Object.assign({}, this.props), React.Children.map(children, (child) => {
|
|
1697
|
+
if (React.isValidElement(child)) {
|
|
1698
|
+
const isTabBar = child.type === IonTabBar ||
|
|
1699
|
+
child.type.isTabBar ||
|
|
1700
|
+
(child.type === Fragment &&
|
|
1701
|
+
(child.props.children[1].type === IonTabBar || child.props.children[1].type.isTabBar));
|
|
1702
|
+
const isRouterOutlet = child.type === IonRouterOutlet ||
|
|
1703
|
+
child.type.isRouterOutlet ||
|
|
1704
|
+
(child.type === Fragment && child.props.children[0].type === IonRouterOutlet);
|
|
1705
|
+
if (isTabBar) {
|
|
1706
|
+
/**
|
|
1707
|
+
* The modified tabBar needs to be returned to include
|
|
1708
|
+
* the context and the overridden methods.
|
|
1709
|
+
*/
|
|
1710
|
+
return tabBar;
|
|
1711
|
+
}
|
|
1712
|
+
if (isRouterOutlet) {
|
|
1713
|
+
/**
|
|
1714
|
+
* The modified outlet needs to be returned to include
|
|
1715
|
+
* the ref.
|
|
1716
|
+
*/
|
|
1717
|
+
return outlet;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
return child;
|
|
1721
|
+
})))) : (React.createElement("div", Object.assign({ className: className ? `${className}` : 'ion-tabs' }, props, { style: hostStyles }),
|
|
1722
|
+
(tabBar === null || tabBar === void 0 ? void 0 : tabBar.props.slot) === 'top' ? tabBar : null,
|
|
1723
|
+
React.createElement("div", { style: tabsInner, className: "tabs-inner" }, outlet),
|
|
1724
|
+
(tabBar === null || tabBar === void 0 ? void 0 : tabBar.props.slot) === 'bottom' ? tabBar : null))));
|
|
1725
|
+
}
|
|
1726
|
+
static get contextType() {
|
|
1727
|
+
return NavContext;
|
|
1728
|
+
}
|
|
1729
|
+
})();
|
|
1730
|
+
|
|
1717
1731
|
const IonBackButton = /*@__PURE__*/ (() => class extends React.Component {
|
|
1718
1732
|
constructor() {
|
|
1719
1733
|
super(...arguments);
|