diff --git a/packages/react/src/components/IonIcon.tsx b/packages/react/src/components/IonIcon.tsx new file mode 100644 index 00000000000..6d9db466649 --- /dev/null +++ b/packages/react/src/components/IonIcon.tsx @@ -0,0 +1,83 @@ +import React from 'react'; + +import { NavContext } from '../contexts/NavContext'; + +import { IonicReactProps } from './IonicReactProps'; +import { IonIconInner } from './inner-proxies'; +import { createForwardRef, isPlatform } from './utils'; +import { deprecationWarning } from './utils/dev'; + +interface IonIconProps { + ariaLabel?: string; + color?: string; + flipRtl?: boolean; + icon?: { ios: string; md: string; }; + ios?: { ios: string; md: string; }; + lazy?: boolean; + md?: { ios: string; md: string; }; + mode?: 'ios' | 'md'; + name?: string; + size?: string; + src?: string; +} + +type InternalProps = IonIconProps & { + forwardedRef?: React.RefObject; +}; + +class IonIconContainer extends React.PureComponent { + + constructor(props: InternalProps) { + super(props); + if (this.props.name) { + deprecationWarning('icon-name', 'In Ionic React, you import icons from "ionicons/icons" and set the icon you imported to the "icon" property. Setting the "name" property has no effect.'); + } + } + + setIcon() { + const { icon, ios, md } = this.props; + if (ios || md) { + if (isPlatform('ios')) { + this.setState({ + icon: ios ?? md ?? icon + }); + } else if (isPlatform('android')) { + this.setState({ + icon: md ?? ios ?? icon + }); + } + } else { + this.setState({ + icon + }); + } + } + + render() { + const { icon, ios, md, ...rest } = this.props; + + let iconToUse: typeof icon; + + if (ios || md) { + if (isPlatform('ios')) { + iconToUse = ios ?? md ?? icon; + } else if (isPlatform('android')) { + iconToUse = md ?? ios ?? icon; + } + } else { + iconToUse = icon; + } + + return ( + + {this.props.children} + + ); + } + + static get contextType() { + return NavContext; + } +} + +export const IonIcon = createForwardRef(IonIconContainer, 'IonIcon'); diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 3d32047cd38..6c5d09f275d 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -22,6 +22,7 @@ export { IonTabs } from './navigation/IonTabs'; export { IonTabBar } from './navigation/IonTabBar'; export { IonBackButton } from './navigation/IonBackButton'; export { IonRouterOutlet } from './IonRouterOutlet'; +export { IonIcon } from './IonIcon'; // Utils export { isPlatform, getPlatforms, getConfig } from './utils'; diff --git a/packages/react/src/components/inner-proxies.ts b/packages/react/src/components/inner-proxies.ts index 375a709cc12..cf353ee38fb 100644 --- a/packages/react/src/components/inner-proxies.ts +++ b/packages/react/src/components/inner-proxies.ts @@ -1,7 +1,11 @@ import { JSX } from '@ionic/core'; +import { JSX as IoniconsJSX } from 'ionicons'; import { /*@__PURE__*/ createReactComponent } from './createComponent'; export const IonTabBarInner = /*@__PURE__*/createReactComponent('ion-tab-bar'); export const IonBackButtonInner = /*@__PURE__*/createReactComponent, HTMLIonBackButtonElement>('ion-back-button'); export const IonRouterOutletInner = /*@__PURE__*/createReactComponent('ion-router-outlet'); + +// ionicons +export const IonIconInner = /*@__PURE__*/createReactComponent('ion-icon'); diff --git a/packages/react/src/components/proxies.ts b/packages/react/src/components/proxies.ts index 685b24a4854..37186493597 100644 --- a/packages/react/src/components/proxies.ts +++ b/packages/react/src/components/proxies.ts @@ -1,12 +1,8 @@ import { JSX } from '@ionic/core'; -import { JSX as IoniconsJSX } from 'ionicons'; import { createReactComponent } from './createComponent'; import { HrefProps } from './hrefprops'; -// ionicons -export const IonIcon = /*@__PURE__*/createReactComponent('ion-icon'); - // ionic/core export const IonApp = /*@__PURE__*/createReactComponent('ion-app'); export const IonTab = /*@__PURE__*/createReactComponent('ion-tab');