@ionic/react 8.8.1-dev.11772745200.1f0e21b1 → 8.8.1-dev.11773168858.1f9c0eb8
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 +65 -34
- package/dist/index.js.map +1 -1
- package/dist/types/components/IonRoute.d.ts +1 -2
- package/dist/types/components/IonRouterOutlet.d.ts +1 -0
- package/dist/types/components/index.d.ts +0 -1
- package/dist/types/contexts/NavContext.d.ts +0 -2
- package/dist/types/routing/NavManager.d.ts +0 -4
- package/dist/types/routing/OutletPageManager.d.ts +1 -0
- package/dist/types/routing/PageManager.d.ts +7 -0
- package/dist/types/routing/RouteManagerContext.d.ts +5 -0
- package/package.json +2 -2
- package/dist/types/components/IonRedirect.d.ts +0 -16
package/dist/index.js
CHANGED
|
@@ -380,9 +380,7 @@ const useIonViewDidLeave = (callback, deps = []) => {
|
|
|
380
380
|
};
|
|
381
381
|
|
|
382
382
|
const NavContext = /*@__PURE__*/ React.createContext({
|
|
383
|
-
getIonRedirect: () => undefined,
|
|
384
383
|
getIonRoute: () => undefined,
|
|
385
|
-
getPageManager: () => undefined,
|
|
386
384
|
getStackManager: () => undefined,
|
|
387
385
|
goBack: (route) => {
|
|
388
386
|
if (typeof window !== 'undefined') {
|
|
@@ -1137,7 +1135,18 @@ class PageManager extends React.PureComponent {
|
|
|
1137
1135
|
super(props);
|
|
1138
1136
|
this.ionPageElementRef = React.createRef();
|
|
1139
1137
|
// React refs must be stable (not created inline).
|
|
1140
|
-
|
|
1138
|
+
// Wrap merged refs to add ion-page-invisible synchronously when element is created
|
|
1139
|
+
const baseMergedRefs = mergeRefs(this.ionPageElementRef, this.props.forwardedRef);
|
|
1140
|
+
this.stableMergedRefs = (node) => {
|
|
1141
|
+
if (node && !node.classList.contains('ion-page-invisible') && !node.classList.contains('ion-page-hidden')) {
|
|
1142
|
+
// Add ion-page-invisible synchronously before first paint (if in an outlet)
|
|
1143
|
+
// This prevents the flash that occurs when componentDidMount runs after paint
|
|
1144
|
+
if (this.context?.isInOutlet?.()) {
|
|
1145
|
+
node.classList.add('ion-page-invisible');
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
baseMergedRefs(node);
|
|
1149
|
+
};
|
|
1141
1150
|
/**
|
|
1142
1151
|
* This binds the scope of the following methods to the class scope.
|
|
1143
1152
|
* The `.bind` method returns a new function, so we need to assign it
|
|
@@ -1149,11 +1158,38 @@ class PageManager extends React.PureComponent {
|
|
|
1149
1158
|
this.ionViewWillLeaveHandler = this.ionViewWillLeaveHandler.bind(this);
|
|
1150
1159
|
this.ionViewDidLeaveHandler = this.ionViewDidLeaveHandler.bind(this);
|
|
1151
1160
|
}
|
|
1161
|
+
parseClasses(className) {
|
|
1162
|
+
if (!className)
|
|
1163
|
+
return new Set();
|
|
1164
|
+
return new Set(className.split(/\s+/).filter(Boolean));
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Updates classList by diffing old/new className props.
|
|
1168
|
+
* Preserves framework-added classes (can-go-back, ion-page-invisible, etc.).
|
|
1169
|
+
*/
|
|
1170
|
+
updateUserClasses(oldClassName, newClassName) {
|
|
1171
|
+
if (!this.ionPageElementRef.current)
|
|
1172
|
+
return;
|
|
1173
|
+
const oldClasses = this.parseClasses(oldClassName);
|
|
1174
|
+
const newClasses = this.parseClasses(newClassName);
|
|
1175
|
+
oldClasses.forEach((cls) => {
|
|
1176
|
+
if (!newClasses.has(cls)) {
|
|
1177
|
+
this.ionPageElementRef.current.classList.remove(cls);
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
newClasses.forEach((cls) => {
|
|
1181
|
+
if (!oldClasses.has(cls)) {
|
|
1182
|
+
this.ionPageElementRef.current.classList.add(cls);
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1152
1186
|
componentDidMount() {
|
|
1153
1187
|
if (this.ionPageElementRef.current) {
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1188
|
+
// Add user classes via DOM manipulation to preserve framework-added classes.
|
|
1189
|
+
// We only set "ion-page" in JSX; user classes are added here.
|
|
1190
|
+
// Note: ion-page-invisible is added in the ref callback (stableMergedRefs) to prevent flash.
|
|
1191
|
+
// The ref callback runs synchronously when the element is created, before the browser paints.
|
|
1192
|
+
this.updateUserClasses(undefined, this.props.className);
|
|
1157
1193
|
this.context.registerIonPage(this.ionPageElementRef.current, this.props.routeInfo);
|
|
1158
1194
|
this.ionPageElementRef.current.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
|
|
1159
1195
|
this.ionPageElementRef.current.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
|
|
@@ -1161,6 +1197,11 @@ class PageManager extends React.PureComponent {
|
|
|
1161
1197
|
this.ionPageElementRef.current.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
|
|
1162
1198
|
}
|
|
1163
1199
|
}
|
|
1200
|
+
componentDidUpdate(prevProps) {
|
|
1201
|
+
if (prevProps.className !== this.props.className) {
|
|
1202
|
+
this.updateUserClasses(prevProps.className, this.props.className);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1164
1205
|
componentWillUnmount() {
|
|
1165
1206
|
if (this.ionPageElementRef.current) {
|
|
1166
1207
|
this.ionPageElementRef.current.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
|
|
@@ -1190,9 +1231,11 @@ class PageManager extends React.PureComponent {
|
|
|
1190
1231
|
render() {
|
|
1191
1232
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1192
1233
|
const { className, children, routeInfo, forwardedRef, ...props } = this.props;
|
|
1234
|
+
// Only set "ion-page" in JSX. User classes are managed via DOM in componentDidMount/componentDidUpdate
|
|
1235
|
+
// to preserve framework-added classes (can-go-back, ion-page-invisible, etc.) when className prop changes.
|
|
1193
1236
|
return (jsx(IonLifeCycleContext.Consumer, { children: (context) => {
|
|
1194
1237
|
this.ionLifeCycleContext = context;
|
|
1195
|
-
return (jsx("div", { className:
|
|
1238
|
+
return (jsx("div", { className: "ion-page", ref: this.stableMergedRefs, ...props, children: children }));
|
|
1196
1239
|
} }));
|
|
1197
1240
|
}
|
|
1198
1241
|
static get contextType() {
|
|
@@ -1331,10 +1374,10 @@ class OutletPageManager extends React.Component {
|
|
|
1331
1374
|
this.ionLifeCycleContext.ionViewDidLeave();
|
|
1332
1375
|
}
|
|
1333
1376
|
render() {
|
|
1334
|
-
const { StackManager, children, routeInfo, ...props } = this.props;
|
|
1377
|
+
const { StackManager, children, routeInfo, id, ...props } = this.props;
|
|
1335
1378
|
return (jsx(IonLifeCycleContext.Consumer, { children: (context) => {
|
|
1336
1379
|
this.ionLifeCycleContext = context;
|
|
1337
|
-
return (jsx(StackManager, { routeInfo: routeInfo, children: jsx(IonRouterOutletInner, { setRef: (val) => (this.ionRouterOutlet = val), ...props, children: children }) }));
|
|
1380
|
+
return (jsx(StackManager, { id: id, routeInfo: routeInfo, children: jsx(IonRouterOutletInner, { id: id, setRef: (val) => (this.ionRouterOutlet = val), ...props, children: children }) }));
|
|
1338
1381
|
} }));
|
|
1339
1382
|
}
|
|
1340
1383
|
static get contextType() {
|
|
@@ -1345,11 +1388,13 @@ class OutletPageManager extends React.Component {
|
|
|
1345
1388
|
class IonRouterOutletContainer extends React.Component {
|
|
1346
1389
|
constructor(props) {
|
|
1347
1390
|
super(props);
|
|
1391
|
+
this.outletId = props.id ?? `routerOutlet-${generateId('routerOutlet')}`;
|
|
1348
1392
|
}
|
|
1349
1393
|
render() {
|
|
1350
1394
|
const StackManager = this.context.getStackManager();
|
|
1351
1395
|
const { children, forwardedRef, ...props } = this.props;
|
|
1352
|
-
|
|
1396
|
+
const outletId = props.id ?? this.outletId;
|
|
1397
|
+
return this.context.hasIonicRouter() ? (props.ionPage ? (jsx(OutletPageManager, { StackManager: StackManager, routeInfo: this.context.routeInfo, ...props, children: children })) : (jsx(StackManager, { routeInfo: this.context.routeInfo, id: outletId, children: jsx(IonRouterOutletInner, { ...props, id: outletId, forwardedRef: forwardedRef, children: children }) }))) : (jsx(IonRouterOutletInner, { ref: forwardedRef, ...this.props, children: this.props.children }));
|
|
1353
1398
|
}
|
|
1354
1399
|
static get contextType() {
|
|
1355
1400
|
return NavContext;
|
|
@@ -1830,20 +1875,6 @@ class IonRoute extends React.PureComponent {
|
|
|
1830
1875
|
}
|
|
1831
1876
|
}
|
|
1832
1877
|
|
|
1833
|
-
class IonRedirect extends React.PureComponent {
|
|
1834
|
-
render() {
|
|
1835
|
-
const IonRedirectInner = this.context.getIonRedirect();
|
|
1836
|
-
if (!this.context.hasIonicRouter() || !IonRedirect) {
|
|
1837
|
-
console.error('You either do not have an Ionic Router package, or your router does not support using <IonRedirect>');
|
|
1838
|
-
return null;
|
|
1839
|
-
}
|
|
1840
|
-
return jsx(IonRedirectInner, { ...this.props });
|
|
1841
|
-
}
|
|
1842
|
-
static get contextType() {
|
|
1843
|
-
return NavContext;
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
1878
|
const IonRouterContext = React.createContext({
|
|
1848
1879
|
routeInfo: undefined, // TODO(FW-2959): type
|
|
1849
1880
|
push: () => {
|
|
@@ -2240,6 +2271,7 @@ const RouteManagerContext = /*@__PURE__*/ React.createContext({
|
|
|
2240
2271
|
findLeavingViewItemByRouteInfo: () => undefined,
|
|
2241
2272
|
findViewItemByRouteInfo: () => undefined,
|
|
2242
2273
|
getChildrenToRender: () => undefined,
|
|
2274
|
+
getViewItemsForOutlet: () => [],
|
|
2243
2275
|
goBack: () => undefined,
|
|
2244
2276
|
unMountViewItem: () => undefined,
|
|
2245
2277
|
});
|
|
@@ -2358,7 +2390,14 @@ class LocationHistory {
|
|
|
2358
2390
|
_replace(routeInfo) {
|
|
2359
2391
|
const routeInfos = this._getRouteInfosByKey(routeInfo.tab);
|
|
2360
2392
|
routeInfos && routeInfos.pop();
|
|
2361
|
-
|
|
2393
|
+
// Get the current route that's being replaced
|
|
2394
|
+
const currentRoute = this.locationHistory[this.locationHistory.length - 1];
|
|
2395
|
+
// Only pop from global history if we're replacing in the same outlet context.
|
|
2396
|
+
// Don't pop if we're entering a nested outlet (current route has no tab, new route has a tab)
|
|
2397
|
+
const isEnteringNestedOutlet = currentRoute && !currentRoute.tab && !!routeInfo.tab;
|
|
2398
|
+
if (!isEnteringNestedOutlet) {
|
|
2399
|
+
this.locationHistory.pop();
|
|
2400
|
+
}
|
|
2362
2401
|
this._add(routeInfo);
|
|
2363
2402
|
}
|
|
2364
2403
|
_clear() {
|
|
@@ -2441,10 +2480,8 @@ class NavManager extends React.PureComponent {
|
|
|
2441
2480
|
goBack: this.goBack.bind(this),
|
|
2442
2481
|
hasIonicRouter: () => true,
|
|
2443
2482
|
navigate: this.navigate.bind(this),
|
|
2444
|
-
getIonRedirect: this.getIonRedirect.bind(this),
|
|
2445
2483
|
getIonRoute: this.getIonRoute.bind(this),
|
|
2446
2484
|
getStackManager: this.getStackManager.bind(this),
|
|
2447
|
-
getPageManager: this.getPageManager.bind(this),
|
|
2448
2485
|
routeInfo: this.props.routeInfo,
|
|
2449
2486
|
setCurrentTab: this.props.onSetCurrentTab,
|
|
2450
2487
|
changeTab: this.props.onChangeTab,
|
|
@@ -2477,12 +2514,6 @@ class NavManager extends React.PureComponent {
|
|
|
2477
2514
|
navigate(path, direction = 'forward', action = 'push', animationBuilder, options, tab) {
|
|
2478
2515
|
this.props.onNavigate(path, action, direction, animationBuilder, options, tab);
|
|
2479
2516
|
}
|
|
2480
|
-
getPageManager() {
|
|
2481
|
-
return PageManager;
|
|
2482
|
-
}
|
|
2483
|
-
getIonRedirect() {
|
|
2484
|
-
return this.props.ionRedirect;
|
|
2485
|
-
}
|
|
2486
2517
|
getIonRoute() {
|
|
2487
2518
|
return this.props.ionRoute;
|
|
2488
2519
|
}
|
|
@@ -2544,5 +2575,5 @@ class ViewStacks {
|
|
|
2544
2575
|
}
|
|
2545
2576
|
}
|
|
2546
2577
|
|
|
2547
|
-
export { CreateAnimation, DefaultIonLifeCycleContext, 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, IonInputOtp, IonInputPasswordToggle, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonLifeCycleContext, IonList, IonListHeader, IonLoading, IonMenu, IonMenuButton, IonMenuToggle, IonModal, IonNav, IonNavLink, IonNote, IonPage, IonPicker, IonPickerColumn, IonPickerColumnOption, IonPickerLegacy, IonPopover, IonProgressBar, IonRadio, IonRadioGroup, IonRange,
|
|
2578
|
+
export { CreateAnimation, DefaultIonLifeCycleContext, 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, IonInputOtp, IonInputPasswordToggle, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonLifeCycleContext, 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, IonRoute, IonRouterContext, IonRouterLink, IonRouterOutlet, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSegmentContent, IonSegmentView, IonSelect, IonSelectModal, IonSelectOption, IonSkeletonText, IonSpinner, IonSplitPane, IonTab, IonTabBar, IonTabButton, IonTabs, IonTabsContext, IonText, IonTextarea, IonThumbnail, IonTitle, IonToast, IonToggle, IonToolbar, LocationHistory, NavContext, NavManager, RouteManagerContext, StackContext, ViewLifeCycleManager, ViewStacks, generateId, getConfig, getPlatforms, isPlatform, setupIonicReact, useIonActionSheet, useIonAlert, useIonLoading, useIonModal, useIonPicker, useIonPopover, useIonRouter, useIonToast, useIonViewDidEnter, useIonViewDidLeave, useIonViewWillEnter, useIonViewWillLeave, withIonLifeCycle };
|
|
2548
2579
|
//# sourceMappingURL=index.js.map
|