Skip to content

Commit

Permalink
fix(react/vue): properly switch ionicon based on the mode when ios/md…
Browse files Browse the repository at this point in the history
… is set (#26924)

closes #26207
  • Loading branch information
brandyscarney committed Mar 14, 2023
1 parent af79673 commit 1eb9a08
Show file tree
Hide file tree
Showing 16 changed files with 383 additions and 14 deletions.
24 changes: 24 additions & 0 deletions core/src/components/icon/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@
</ion-label>
</ion-item>

<ion-item>
<ion-icon slot="start" ios="star-outline" md="star"></ion-icon>
<ion-label>
<p>ios: star outline</p>
<p>md: star</p>
</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" mode="ios" ios="star-outline" md="star"></ion-icon>
<ion-label>
<h3>mode: ios</h3>
<p>ios: star outline</p>
<p>md: star</p>
</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" mode="md" ios="star-outline" md="star"></ion-icon>
<ion-label>
<h3>mode: md</h3>
<p>ios: star outline</p>
<p>md: star</p>
</ion-label>
</ion-item>

<ion-item detail="true">
<ion-label>
<code> ion-item w/ [detail="true"] attr. text text text text text text </code>
Expand Down
9 changes: 6 additions & 3 deletions packages/react/src/components/IonIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NavContext } from '../contexts/NavContext';

import type { IonicReactProps } from './IonicReactProps';
import { IonIconInner } from './inner-proxies';
import { createForwardRef, isPlatform } from './utils';
import { createForwardRef, getConfig } from './utils';

interface IonIconProps {
color?: string;
Expand Down Expand Up @@ -34,12 +34,15 @@ class IonIconContainer extends React.PureComponent<InternalProps> {
}

render() {
const { icon, ios, md, ...rest } = this.props;
const { icon, ios, md, mode, ...rest } = this.props;

let iconToUse: typeof icon;

const config = getConfig();
const iconMode = mode || config?.get('mode');

if (ios || md) {
if (isPlatform('ios')) {
if (iconMode === 'ios') {
iconToUse = ios ?? md ?? icon;
} else {
iconToUse = md ?? ios ?? icon;
Expand Down
47 changes: 47 additions & 0 deletions packages/react/test-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# React Test App

## Getting Started

### Setup

Make sure you are using the latest versions of node and npm. If you do not have these, [download the installer](https://nodejs.org/) for the LTS version of Node.js. This is the best way to also [install npm](https://blog.npmjs.org/post/85484771375/how-to-install-npm#_=_).

### Building Dependencies

Navigate to the `core`, `packages/react` and `packages/react-router` directories and build each of them:

```bash
npm i
npm run build
```

Then, install dependencies from this directory for this test app:

```
npm i
```

### Syncing Changes

When making changes to the React package, run the following from this directory to sync the changes:

```bash
npm run sync
```

### Previewing App

To preview this app locally, run the following from this directory:

```bash
npm start
```

### Running Tests

To run the e2e tests, run the following from this directory:

```
npm run build
npm run e2e
```
1 change: 1 addition & 0 deletions packages/react/test-app/public/assets/logo-android.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/react/test-app/public/assets/logo-apple.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/react/test-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import OverlayHooks from './pages/overlay-hooks/OverlayHooks';
import OverlayComponents from './pages/overlay-components/OverlayComponents';
import KeepContentsMounted from './pages/overlay-components/KeepContentsMounted';
import Tabs from './pages/Tabs';
import Icons from './pages/Icons';
import NavComponent from './pages/navigation/NavComponent';
import IonModalConditionalSibling from './pages/overlay-components/IonModalConditionalSibling';
import IonModalConditional from './pages/overlay-components/IonModalConditional';
Expand Down Expand Up @@ -54,6 +55,7 @@ const App: React.FC = () => (
<Route path="/keep-contents-mounted" component={KeepContentsMounted} />
<Route path="/navigation" component={NavComponent} />
<Route path="/tabs" component={Tabs} />
<Route path="/icons" component={Icons} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
Expand Down
95 changes: 95 additions & 0 deletions packages/react/test-app/src/pages/Icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useState } from 'react';
import { IonBackButton, IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/react';
import { heart, heartCircleOutline, logoApple, logoTwitter, personCircleOutline, star, starOutline, trash } from 'ionicons/icons';

interface IconsProps {}

const Icons: React.FC<IconsProps> = () => {
const [dynamic, setDynamic] = useState(star);
const iosCustomSvg = "../assets/logo-apple.svg";
const mdCustomSvg = "../assets/logo-android.svg";

const toggle = () => {
setDynamic(dynamic => dynamic === star ? starOutline : star);
}

return (
<>
<IonHeader translucent={true}>
<IonToolbar>
<IonButtons>
<IonBackButton></IonBackButton>
</IonButtons>
<IonTitle>Icons</IonTitle>
</IonToolbar>
</IonHeader>

<IonContent fullscreen={true}>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Icons</IonTitle>
</IonToolbar>
</IonHeader>

<IonList>
<IonItem>
<IonIcon slot="start" icon={heart}></IonIcon>
<IonLabel>Static Icons</IonLabel>
<IonIcon slot="end" icon={personCircleOutline} color="dark"></IonIcon>
<IonIcon slot="end" icon={trash} color="danger"></IonIcon>
</IonItem>
<IonItem>
<IonIcon icon={logoApple} slot="start"></IonIcon>
<IonLabel>Logo Icons</IonLabel>
<IonIcon icon={logoTwitter} slot="end"></IonIcon>
</IonItem>
<IonItem>
<IonIcon slot="start" icon={dynamic} color="warning"></IonIcon>
<IonLabel>Dynamic Icon</IonLabel>
<IonButton slot="end" fill="outline" onClick={() => toggle()}>
Toggle Icon
</IonButton>
</IonItem>
<IonItem>
<IonIcon slot="start" ios={heartCircleOutline} md={personCircleOutline}></IonIcon>
<IonLabel>
<p>ios: heart circle</p>
<p>md: person circle</p>
</IonLabel>
</IonItem>
<IonItem>
<IonIcon slot="start" ios={starOutline} md={star}></IonIcon>
<IonLabel>
<p>ios: star outline</p>
<p>md: star</p>
</IonLabel>
</IonItem>
<IonItem>
<IonIcon slot="start" mode="ios" ios={starOutline} md={star}></IonIcon>
<IonLabel>
<h3>mode: ios</h3>
<p>ios: star outline</p>
<p>md: star</p>
</IonLabel>
</IonItem>
<IonItem>
<IonIcon slot="start" mode="md" ios={starOutline} md={star}></IonIcon>
<IonLabel>
<h3>mode: md</h3>
<p>ios: star outline</p>
<p>md: star</p>
</IonLabel>
</IonItem>
<IonItem>
<IonIcon id="customSvg" slot="start" ios={iosCustomSvg} md={mdCustomSvg}></IonIcon>
<IonLabel>
<p>Custom SVG</p>
</IonLabel>
</IonItem>
</IonList>
</IonContent>
</>
);
};

export default Icons;
11 changes: 3 additions & 8 deletions packages/react/test-app/src/pages/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,21 @@ const Main: React.FC<MainProps> = () => {
<IonItem routerLink="/overlay-hooks">
<IonLabel>Overlay Hooks</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/overlay-components">
<IonLabel>Overlay Components</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/keep-contents-mounted">
<IonLabel>Keep Contents Mounted Overlay Components</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/navigation">
<IonLabel>Navigation</IonLabel>
</IonItem>
</IonList>
<IonList>
<IonItem routerLink="/tabs">
<IonLabel>Tabs</IonLabel>
</IonItem>
<IonItem routerLink="/icons">
<IonLabel>Icons</IonLabel>
</IonItem>
</IonList>
</IonContent>
</IonPage>
Expand Down
22 changes: 22 additions & 0 deletions packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
describe('Icons', () => {
it('should use ios svg', () => {
cy.visit('/icons?ionic:mode=ios');

cy.get('#customSvg').shadow().find('svg').should('have.class', 'ios');
cy.get('#customSvg').shadow().find('svg').should('have.class', 'apple');
});

it('should use md svg', () => {
cy.visit('/icons?ionic:mode=md');

cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
});

it('should use fallback md svg', () => {
cy.visit('/icons');

cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
});
})
11 changes: 8 additions & 3 deletions packages/vue/src/components/IonIcon.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { isPlatform } from "@ionic/core/components";
import { defineCustomElement } from "ionicons/components/ion-icon.js";
import { h, defineComponent } from "vue";

import { getConfig } from "../utils";

export const IonIcon = /*@__PURE__*/ defineComponent({
name: "IonIcon",
props: {
Expand All @@ -19,11 +20,15 @@ export const IonIcon = /*@__PURE__*/ defineComponent({
setup(props, { slots }) {
defineCustomElement();
return () => {
const { icon, ios, md } = props;
const { icon, ios, md, mode } = props;

let iconToUse: typeof icon;

const config = getConfig();
const iconMode = mode || config?.get("mode");

if (ios || md) {
if (isPlatform("ios")) {
if (iconMode === "ios") {
iconToUse = ios ?? md ?? icon;
} else {
iconToUse = md ?? ios ?? icon;
Expand Down
1 change: 1 addition & 0 deletions packages/vue/test/base/public/assets/logo-android.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/vue/test/base/public/assets/logo-apple.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/vue/test/base/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const routes: Array<RouteRecordRaw> = [
path: '/keep-contents-mounted',
component: () => import('@/views/OverlaysKeepContentsMounted.vue')
},
{
path: '/icons',
component: () => import('@/views/Icons.vue')
},
{
path: '/inputs',
component: () => import('@/views/Inputs.vue')
Expand Down
3 changes: 3 additions & 0 deletions packages/vue/test/base/src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<ion-item button router-link="/overlays">
<ion-label>Overlays</ion-label>
</ion-item>
<ion-item button router-link="/icons">
<ion-label>Icons</ion-label>
</ion-item>
<ion-item button router-link="/inputs">
<ion-label>Inputs</ion-label>
</ion-item>
Expand Down

0 comments on commit 1eb9a08

Please sign in to comment.