merge release-6.1.14

Release 6.1.14
This commit is contained in:
Liam DeBeasi
2022-07-13 09:54:54 -04:00
committed by GitHub
119 changed files with 536 additions and 194 deletions

View File

@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.1.14](https://github.com/ionic-team/ionic/compare/v6.1.13...v6.1.14) (2022-07-13)
### Bug Fixes
* **react:** IonNav works with react ([#25565](https://github.com/ionic-team/ionic/issues/25565)) ([420f9bb](https://github.com/ionic-team/ionic/commit/420f9bbebd41f3eab6def795bcdd1933d5c5a47a)), closes [#24002](https://github.com/ionic-team/ionic/issues/24002)
## [6.1.13](https://github.com/ionic-team/ionic/compare/v6.1.12...v6.1.13) (2022-07-06)
**Note:** Version bump only for package @ionic/react

View File

@ -1,15 +1,15 @@
{
"name": "@ionic/react",
"version": "6.1.13",
"version": "6.1.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/react",
"version": "6.1.13",
"version": "6.1.14",
"license": "MIT",
"dependencies": {
"@ionic/core": "^6.1.13",
"@ionic/core": "^6.1.14",
"ionicons": "^6.0.2",
"tslib": "*"
},
@ -607,9 +607,9 @@
}
},
"node_modules/@ionic/core": {
"version": "6.1.13",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.13.tgz",
"integrity": "sha512-CZ5P1El/bk6ZDKqey/67/ZgpUhVQTr+WyhGxFTnPCsIWg+VfOogQ7rHCkEqWfXJqdzNPsvtH5/Lck4qoD0nCkg==",
"version": "6.1.14",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.14.tgz",
"integrity": "sha512-tmhumOD7VM7QV3boh8rwMNYOgqBskOtGJPSEaySEmCUy+Y0nXwb0gBqxZ/M6c0JcGwT17gIB2KiQDvZ4O/J8iA==",
"dependencies": {
"@stencil/core": "^2.16.0",
"ionicons": "^6.0.2",
@ -9522,9 +9522,9 @@
}
},
"@ionic/core": {
"version": "6.1.13",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.13.tgz",
"integrity": "sha512-CZ5P1El/bk6ZDKqey/67/ZgpUhVQTr+WyhGxFTnPCsIWg+VfOogQ7rHCkEqWfXJqdzNPsvtH5/Lck4qoD0nCkg==",
"version": "6.1.14",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.14.tgz",
"integrity": "sha512-tmhumOD7VM7QV3boh8rwMNYOgqBskOtGJPSEaySEmCUy+Y0nXwb0gBqxZ/M6c0JcGwT17gIB2KiQDvZ4O/J8iA==",
"requires": {
"@stencil/core": "^2.16.0",
"ionicons": "^6.0.2",

View File

@ -1,6 +1,6 @@
{
"name": "@ionic/react",
"version": "6.1.13",
"version": "6.1.14",
"description": "React specific wrapper for @ionic/core",
"keywords": [
"ionic",
@ -41,7 +41,7 @@
"css/"
],
"dependencies": {
"@ionic/core": "^6.1.13",
"@ionic/core": "^6.1.14",
"ionicons": "^6.0.2",
"tslib": "*"
},

View File

@ -132,6 +132,7 @@ export { IonPopover } from './IonPopover';
// Custom Components
export { IonApp } from './IonApp';
export { IonPage } from './IonPage';
export { IonNav } from './navigation/IonNav';
export { IonTabsContext, IonTabsContextState } from './navigation/IonTabsContext';
export { IonTabs } from './navigation/IonTabs';
export { IonTabBar } from './navigation/IonTabBar';

View File

@ -21,7 +21,15 @@ export const IonBackButton = /*@__PURE__*/ (() =>
context!: React.ContextType<typeof NavContext>;
clickButton = (e: React.MouseEvent) => {
/**
* If ion-back-button is being used inside
* of ion-nav then we should not interact with
* the router.
*/
if (e.target && (e.target as HTMLElement).closest('ion-nav') !== null) { return; }
const { defaultHref, routerAnimation } = this.props;
if (this.context.hasIonicRouter()) {
e.stopPropagation();
this.context.goBack(defaultHref, routerAnimation);

View File

@ -0,0 +1,30 @@
import type { FrameworkDelegate, JSX } from '@ionic/core/components';
import { defineCustomElement } from '@ionic/core/components/ion-nav.js';
import React, { useState } from 'react';
import { ReactDelegate } from '../../framework-delegate';
import { createReactComponent } from '../react-component-lib';
const IonNavInner = createReactComponent<
JSX.IonNav & { delegate: FrameworkDelegate },
HTMLIonNavElement
>('ion-nav', undefined, undefined, defineCustomElement);
export const IonNav: React.FC<JSX.IonNav> = ({ children, ...restOfProps }) => {
const [views, setViews] = useState<React.ReactPortal[]>([]);
/**
* Allows us to create React components that are rendered within
* the context of the IonNav component.
*/
const addView = (view: React.ReactPortal) => setViews([...views, view]);
const removeView = (view: React.ReactPortal) => setViews(views.filter((v) => v !== view));
const delegate = ReactDelegate(addView, removeView);
return (
<IonNavInner delegate={delegate} {...restOfProps}>
{views}
</IonNavInner>
);
};

View File

@ -0,0 +1,38 @@
import { FrameworkDelegate } from '@ionic/core/components';
import { createPortal } from 'react-dom';
export const ReactDelegate = (
addView: (view: React.ReactPortal) => void,
removeView: (view: React.ReactPortal) => void
): FrameworkDelegate => {
let Component: React.ReactPortal;
const attachViewToDom = async (
parentElement: HTMLElement,
component: () => JSX.Element,
propsOrDataObj?: any,
cssClasses?: string[]
): Promise<any> => {
const div = document.createElement('div');
cssClasses && div.classList.add(...cssClasses);
parentElement.appendChild(div);
Component = createPortal(component(), div);
Component.props = propsOrDataObj;
addView(Component);
return Promise.resolve(div);
};
const removeViewFromDom = (): Promise<void> => {
Component && removeView(Component);
return Promise.resolve();
};
return {
attachViewToDom,
removeViewFromDom,
};
};

View File

@ -0,0 +1,28 @@
describe('IonNav', () => {
beforeEach(() => {
cy.visit('/navigation');
});
it('should render the root page', () => {
cy.get('ion-nav').contains('Page one content');
});
it('should push a page', () => {
cy.get('ion-button').contains('Go to Page Two').click();
cy.get('#pageTwoContent').should('be.visible');
cy.get('ion-nav').contains('Page two content');
});
it('should pop a page', () => {
cy.get('ion-button').contains('Go to Page Two').click();
cy.get('#pageTwoContent').should('be.visible');
cy.get('ion-nav').contains('Page two content');
cy.get('.ion-page.can-go-back ion-back-button').click();
cy.get('#pageOneContent').should('be.visible');
cy.get('ion-nav').contains('Page one content');
});
});

View File

@ -25,6 +25,7 @@ import Main from './pages/Main';
import OverlayHooks from './pages/overlay-hooks/OverlayHooks';
import OverlayComponents from './pages/overlay-components/OverlayComponents';
import Tabs from './pages/Tabs';
import NavComponent from './pages/navigation/NavComponent';
setupIonicReact();
@ -35,6 +36,7 @@ const App: React.FC = () => (
<Route path="/" component={Main} />
<Route path="/overlay-hooks" component={OverlayHooks} />
<Route path="/overlay-components" component={OverlayComponents} />
<Route path="/navigation" component={NavComponent} />
<Route path="/tabs" component={Tabs} />
</IonRouterOutlet>
</IonReactRouter>

View File

@ -31,6 +31,11 @@ const Main: React.FC<MainProps> = () => {
<IonLabel>Overlay Components</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/navigation">
<IonLabel>Navigation</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/tabs">
<IonLabel>Tabs</IonLabel>

View File

@ -0,0 +1,84 @@
import {
IonButton,
IonContent,
IonHeader,
IonLabel,
IonNav,
IonNavLink,
IonTitle,
IonToolbar,
IonButtons,
IonBackButton,
IonPage,
} from '@ionic/react';
import React from 'react';
const NavComponent: React.FC = () => {
return (
<IonPage>
<IonNav
root={() => {
return (
<>
<IonHeader>
<IonToolbar>
<IonTitle>Page One</IonTitle>
<IonButtons>
<IonBackButton />
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent id="pageOneContent">
<IonLabel>Page one content</IonLabel>
<IonNavLink
routerDirection="forward"
component={() => {
return (
<>
<IonHeader>
<IonToolbar>
<IonTitle>Page Two</IonTitle>
<IonButtons>
<IonBackButton />
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent id="pageTwoContent">
<IonLabel>Page two content</IonLabel>
<IonNavLink
routerDirection="forward"
component={() => (
<>
<IonHeader>
<IonToolbar>
<IonTitle>Page Three</IonTitle>
<IonButtons>
<IonBackButton />
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>
<IonLabel>Page three content</IonLabel>
</IonContent>
</>
)}
>
<IonButton>Go to Page Three</IonButton>
</IonNavLink>
</IonContent>
</>
);
}}
>
<IonButton>Go to Page Two</IonButton>
</IonNavLink>
</IonContent>
</>
);
}}
></IonNav>
</IonPage>
);
};
export default NavComponent;

View File

@ -49,7 +49,7 @@ const ModalHook: React.FC = () => {
setCount(count + 1);
}, [count, setCount]);
const handleDismissWithComponent = useCallback((data, role) => {
const handleDismissWithComponent = useCallback((data: any, role: string) => {
dismissWithComponent(data, role);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);