2
0
mirror of https://github.com/iconify/iconify.git synced 2024-09-19 16:59:02 +00:00

Clean up code for React with API for new React component compatibility

This commit is contained in:
Vjacheslav Trushkin 2021-01-27 11:45:03 +02:00
parent 6505545902
commit f926986eb6
6 changed files with 67 additions and 22 deletions

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Icon, InlineIcon, enableCache } from '@iconify/react-with-api';
import { Icon, InlineIcon, disableCache } from '@iconify/react-with-api';
import accountIcon from '@iconify-icons/mdi-light/account';
import homeIcon from '@iconify-icons/mdi-light/home';
@ -9,8 +9,7 @@ import { InlineDemo } from './components/Inline';
import './App.css';
// Disable cache for test
enableCache('local', false);
enableCache('session', false);
disableCache('all');
class CheckboxIcon extends React.Component {
constructor(props) {
@ -125,6 +124,26 @@ function App() {
}}
/>
</p>
<p>
Testing reference by adding border to icon (unfortunately
should not work yet):{' '}
<Icon
icon="mdi-light:alert"
ref={(element) => {
if (element) {
element.style.border = '1px solid red';
}
}}
/>
<Icon
icon={accountIcon}
ref={(element) => {
if (element) {
element.style.border = '1px solid red';
}
}}
/>
</p>
</section>
<InlineDemo />

View File

@ -1,12 +1,12 @@
{
"name": "@iconify/react-with-api",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@iconify/react-with-api",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.12.7",

View File

@ -2,7 +2,7 @@
"name": "@iconify/react-with-api",
"description": "Iconify icon component for React.",
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"license": "MIT",
"bugs": "https://github.com/iconify/iconify/issues",
"homepage": "https://iconify.design/",

View File

@ -33,7 +33,13 @@ const config = [
},
],
external: ['react', 'axios'],
plugins: [resolve(), commonjs(), buble()],
plugins: [
resolve(),
commonjs({
ignore: ['cross-fetch'],
}),
buble(),
],
},
// Dev build
{
@ -45,7 +51,13 @@ const config = [
},
],
external: ['react', 'axios'],
plugins: [resolve(), commonjs(), buble()],
plugins: [
resolve(),
commonjs({
ignore: ['cross-fetch'],
}),
buble(),
],
},
// Production
{
@ -57,7 +69,14 @@ const config = [
},
],
external: ['react', 'axios'],
plugins: [resolve(), commonjs(), buble(), terser()],
plugins: [
resolve(),
commonjs({
ignore: ['cross-fetch'],
}),
buble(),
terser(),
],
},
];

View File

@ -1,4 +1,4 @@
import { createElement, Component } from 'react';
import React from 'react';
import { IconifyJSON } from '@iconify/types';
// Parent component
@ -184,7 +184,7 @@ interface StatefulState {
/**
* Dynamic component
*/
class DynamicComponent extends Component<StatefulProps, StatefulState> {
class DynamicComponent extends React.Component<StatefulProps, StatefulState> {
protected _abort: IconifyIconLoaderAbort | null;
/**
@ -215,17 +215,19 @@ class DynamicComponent extends Component<StatefulProps, StatefulState> {
const state = this.state;
if (!state.loaded) {
// Empty
return null;
return React.createElement('span');
}
// Replace icon in props with object
const props = this.props;
let newProps: IconProps = {} as IconProps;
Object.assign(newProps, this.props, {
Object.assign(newProps, props, {
icon: state.data,
});
delete newProps['func'];
delete newProps.ref;
return this.props.func(newProps);
return React.createElement(this.props.func, newProps);
}
/**
@ -267,7 +269,7 @@ const component = (props: IconProps, func: typeof ReactIcon): JSX.Element => {
if (typeof props.icon === 'string') {
const iconName = stringToIcon(props.icon, true);
if (!iconName) {
return null;
return React.createElement('span');
}
iconData = getIconData(iconName);
@ -276,7 +278,7 @@ const component = (props: IconProps, func: typeof ReactIcon): JSX.Element => {
let staticProps: IconProps = {} as IconProps;
Object.assign(staticProps, props);
staticProps.icon = iconData;
return func(staticProps);
return React.createElement(func, staticProps);
}
// Return dynamic component
@ -285,9 +287,10 @@ const component = (props: IconProps, func: typeof ReactIcon): JSX.Element => {
icon: iconName,
func,
});
return createElement(DynamicComponent, dynamicProps);
return React.createElement(DynamicComponent, dynamicProps);
} else {
return func(props);
// Passed icon data as object: render @iconify/react component
return React.createElement(func, props);
}
};

View File

@ -60,10 +60,14 @@ export interface IconifyIconProps extends IconifyIconCustomisations {
type IconifyElementProps = HTMLProps<HTMLElement>;
type IconifySVGProps = SVGProps<SVGElement>;
interface ReactRefProp {
ref?: typeof React.createRef;
}
/**
* Mix of icon properties and HTMLElement properties
*/
export type IconProps = IconifyElementProps & IconifyIconProps;
export type IconProps = IconifyElementProps & IconifyIconProps & ReactRefProp;
/**
* Default SVG attributes
@ -105,7 +109,7 @@ const component = (
? storage[props.icon]
: fullIcon(props.icon);
if (!icon) {
return null;
return React.createElement('span');
}
const customisations = merge(
@ -195,7 +199,7 @@ const component = (
*
* @param props - Component properties
*/
export const Icon = React.forwardRef((props: IconProps, ref) =>
export const Icon = React.forwardRef((props: IconProps, ref?) =>
component(props, defaults, ref)
);
@ -204,7 +208,7 @@ export const Icon = React.forwardRef((props: IconProps, ref) =>
*
* @param props - Component properties
*/
export const InlineIcon = React.forwardRef((props: IconProps, ref) =>
export const InlineIcon = React.forwardRef((props: IconProps, ref?) =>
component(props, inlineDefaults, ref)
);