diff --git a/core/src/components/icon/test/basic/index.html b/core/src/components/icon/test/basic/index.html
index 1295cd4af5..e6ea0961b3 100644
--- a/core/src/components/icon/test/basic/index.html
+++ b/core/src/components/icon/test/basic/index.html
@@ -87,6 +87,30 @@
+
+
+
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: ios
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: md
+ ios: star outline
+ md: star
+
+
+
ion-item w/ [detail="true"] attr. text text text text text text
diff --git a/packages/react/src/components/IonIcon.tsx b/packages/react/src/components/IonIcon.tsx
index 8d782d5348..a873f3c457 100644
--- a/packages/react/src/components/IonIcon.tsx
+++ b/packages/react/src/components/IonIcon.tsx
@@ -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;
@@ -34,12 +34,15 @@ class IonIconContainer extends React.PureComponent {
}
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;
diff --git a/packages/react/test-app/README.md b/packages/react/test-app/README.md
new file mode 100644
index 0000000000..10e49c2b06
--- /dev/null
+++ b/packages/react/test-app/README.md
@@ -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
+```
diff --git a/packages/react/test-app/public/assets/logo-android.svg b/packages/react/test-app/public/assets/logo-android.svg
new file mode 100644
index 0000000000..36d03ecea6
--- /dev/null
+++ b/packages/react/test-app/public/assets/logo-android.svg
@@ -0,0 +1 @@
+
diff --git a/packages/react/test-app/public/assets/logo-apple.svg b/packages/react/test-app/public/assets/logo-apple.svg
new file mode 100644
index 0000000000..838eb7cca7
--- /dev/null
+++ b/packages/react/test-app/public/assets/logo-apple.svg
@@ -0,0 +1 @@
+
diff --git a/packages/react/test-app/src/App.tsx b/packages/react/test-app/src/App.tsx
index c6bf826508..2003e4295b 100644
--- a/packages/react/test-app/src/App.tsx
+++ b/packages/react/test-app/src/App.tsx
@@ -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';
@@ -54,6 +55,7 @@ const App: React.FC = () => (
+
diff --git a/packages/react/test-app/src/pages/Icons.tsx b/packages/react/test-app/src/pages/Icons.tsx
new file mode 100644
index 0000000000..caf9f0b4e6
--- /dev/null
+++ b/packages/react/test-app/src/pages/Icons.tsx
@@ -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 = () => {
+ 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 (
+ <>
+
+
+
+
+
+ Icons
+
+
+
+
+
+
+ Icons
+
+
+
+
+
+
+ Static Icons
+
+
+
+
+
+ Logo Icons
+
+
+
+
+ Dynamic Icon
+ toggle()}>
+ Toggle Icon
+
+
+
+
+
+ ios: heart circle
+ md: person circle
+
+
+
+
+
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: ios
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: md
+ ios: star outline
+ md: star
+
+
+
+
+
+ Custom SVG
+
+
+
+
+ >
+ );
+};
+
+export default Icons;
diff --git a/packages/react/test-app/src/pages/Main.tsx b/packages/react/test-app/src/pages/Main.tsx
index c5f097357d..0d95f9d0ef 100644
--- a/packages/react/test-app/src/pages/Main.tsx
+++ b/packages/react/test-app/src/pages/Main.tsx
@@ -25,26 +25,21 @@ const Main: React.FC = () => {
Overlay Hooks
-
-
Overlay Components
-
-
Keep Contents Mounted Overlay Components
-
-
Navigation
-
-
Tabs
+
+ Icons
+
diff --git a/packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts b/packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts
new file mode 100644
index 0000000000..5e6d8f4003
--- /dev/null
+++ b/packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts
@@ -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');
+ });
+})
diff --git a/packages/vue/src/components/IonIcon.ts b/packages/vue/src/components/IonIcon.ts
index dea7ca86ab..9840652f8d 100644
--- a/packages/vue/src/components/IonIcon.ts
+++ b/packages/vue/src/components/IonIcon.ts
@@ -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: {
@@ -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;
diff --git a/packages/vue/test/base/public/assets/logo-android.svg b/packages/vue/test/base/public/assets/logo-android.svg
new file mode 100644
index 0000000000..36d03ecea6
--- /dev/null
+++ b/packages/vue/test/base/public/assets/logo-android.svg
@@ -0,0 +1 @@
+
diff --git a/packages/vue/test/base/public/assets/logo-apple.svg b/packages/vue/test/base/public/assets/logo-apple.svg
new file mode 100644
index 0000000000..838eb7cca7
--- /dev/null
+++ b/packages/vue/test/base/public/assets/logo-apple.svg
@@ -0,0 +1 @@
+
diff --git a/packages/vue/test/base/src/router/index.ts b/packages/vue/test/base/src/router/index.ts
index d67ca47993..51f037d969 100644
--- a/packages/vue/test/base/src/router/index.ts
+++ b/packages/vue/test/base/src/router/index.ts
@@ -33,6 +33,10 @@ const routes: Array = [
path: '/keep-contents-mounted',
component: () => import('@/views/OverlaysKeepContentsMounted.vue')
},
+ {
+ path: '/icons',
+ component: () => import('@/views/Icons.vue')
+ },
{
path: '/inputs',
component: () => import('@/views/Inputs.vue')
diff --git a/packages/vue/test/base/src/views/Home.vue b/packages/vue/test/base/src/views/Home.vue
index 2d0e6a875a..0ce1b7cab0 100644
--- a/packages/vue/test/base/src/views/Home.vue
+++ b/packages/vue/test/base/src/views/Home.vue
@@ -20,6 +20,9 @@
Overlays
+
+ Icons
+
Inputs
diff --git a/packages/vue/test/base/src/views/Icons.vue b/packages/vue/test/base/src/views/Icons.vue
new file mode 100644
index 0000000000..f44e3516b1
--- /dev/null
+++ b/packages/vue/test/base/src/views/Icons.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+ Icons
+
+
+
+
+
+
+ Icons
+
+
+
+
+
+
+ Static Icons
+
+
+
+
+
+ Logo Icons
+
+
+
+
+ Dynamic Icon
+
+ Toggle Icon
+
+
+
+
+
+ ios: heart circle
+ md: person circle
+
+
+
+
+
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: ios
+ ios: star outline
+ md: star
+
+
+
+
+
+ mode: md
+ ios: star outline
+ md: star
+
+
+
+
+
+ Custom SVG
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/vue/test/base/tests/e2e/specs/icons.cy.js b/packages/vue/test/base/tests/e2e/specs/icons.cy.js
new file mode 100644
index 0000000000..cdf34a0130
--- /dev/null
+++ b/packages/vue/test/base/tests/e2e/specs/icons.cy.js
@@ -0,0 +1,22 @@
+describe('Icons', () => {
+ it('should use ios svg', () => {
+ cy.visit('http://localhost:8080/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('http://localhost:8080/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('http://localhost:8080/icons');
+
+ cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
+ cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
+ });
+})