Skip to content

Commit

Permalink
fix: insert css only in browser (ant-design#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
vagusX committed Aug 11, 2019
1 parent 92a8f66 commit a7d8906
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 132 deletions.
131 changes: 66 additions & 65 deletions packages/icons-react/src/components/AntdIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,72 +17,73 @@ export interface IconComponentProps extends AntdIconProps {
// Initial setting
setTwoToneColor('#1890ff');

class Icon extends React.Component<IconComponentProps> {
static displayName = 'AntdIcon';

static getTwoToneColor = getTwoToneColor;

static setTwoToneColor = setTwoToneColor;

render() {
const {
// affect outter <i>...</i>
className,

// affect inner <svg>...</svg>
icon,
spin,
rotate,

tabIndex,
onClick,

// other
twoToneColor,

...restProps
} = this.props;

const classString = classNames(
'anticon',
{ [`anticon-${icon.name}`]: Boolean(icon.name) },
className,
);

const svgClassString = classNames({
'anticon-spin': !!spin || icon.name === 'loading',
});

let iconTabIndex = tabIndex;
if (iconTabIndex === undefined && onClick) {
iconTabIndex = -1;
}

const svgStyle = rotate
? {
msTransform: `rotate(${rotate}deg)`,
transform: `rotate(${rotate}deg)`,
}
: undefined;

return (
<span
role="img"
aria-label={icon.name}
{...restProps}
tabIndex={iconTabIndex}
onClick={onClick}
className={classString}
>
<ReactIcon
className={svgClassString}
icon={icon}
primaryColor={twoToneColor}
style={svgStyle}
/>
</span>
);
interface IconBaseComponent<P> extends React.FC<P> {
getTwoToneColor: typeof getTwoToneColor;
setTwoToneColor: typeof setTwoToneColor;
}

const Icon: IconBaseComponent<IconComponentProps> = props => {
const {
// affect outter <i>...</i>
className,

// affect inner <svg>...</svg>
icon,
spin,
rotate,

tabIndex,
onClick,

// other
twoToneColor,

...restProps
} = props;

const classString = classNames(
'anticon',
{ [`anticon-${icon.name}`]: Boolean(icon.name) },
className,
);

const svgClassString = classNames({
'anticon-spin': !!spin || icon.name === 'loading',
});

let iconTabIndex = tabIndex;
if (iconTabIndex === undefined && onClick) {
iconTabIndex = -1;
}

const svgStyle = rotate
? {
msTransform: `rotate(${rotate}deg)`,
transform: `rotate(${rotate}deg)`,
}
: undefined;

return (
<span
role="img"
aria-label={icon.name}
{...restProps}
tabIndex={iconTabIndex}
onClick={onClick}
className={classString}
>
<ReactIcon
className={svgClassString}
icon={icon}
primaryColor={twoToneColor}
style={svgStyle}
/>
</span>
);
}

Icon.displayName = 'AntdIcon';
Icon.getTwoToneColor = getTwoToneColor;
Icon.setTwoToneColor = setTwoToneColor;

export default Icon;
4 changes: 3 additions & 1 deletion packages/icons-react/src/components/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import classNames from 'classnames';

import { svgBaseProps, log } from '../utils';
import { svgBaseProps, log, useInsertStyles } from '../utils';

export interface IconBaseProps {
tabIndex?: number;
Expand Down Expand Up @@ -54,6 +54,8 @@ const Icon: React.FC<IconComponentProps> = props => {
'Should have `type` prop or `component` prop or `children`.',
);

useInsertStyles();

const classString = classNames(
'anticon',
className,
Expand Down
118 changes: 63 additions & 55 deletions packages/icons-react/src/components/IconBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getSecondaryColor,
isIconDefinition,
log,
useInsertStyles,
} from '../utils';

export interface IconProps {
Expand All @@ -31,71 +32,78 @@ const twoToneColorPalette: TwoToneColorPalette = {
secondaryColor: '#E6E6E6',
};

class Icon extends React.Component<IconProps> {
static displayName = 'IconReact';
function setTwoToneColors({
primaryColor,
secondaryColor,
}: TwoToneColorPaletteSetter) {
twoToneColorPalette.primaryColor = primaryColor;
twoToneColorPalette.secondaryColor =
secondaryColor || getSecondaryColor(primaryColor);
}

function getTwoToneColors(): TwoToneColorPalette {
return {
...twoToneColorPalette,
};
}

static setTwoToneColors({
interface IconBaseComponent<P> extends React.FC<P> {
getTwoToneColors: typeof getTwoToneColors;
setTwoToneColors: typeof setTwoToneColors;
}

const IconBase: IconBaseComponent<IconProps> = props => {
const {
icon,
className,
onClick,
style,
primaryColor,
secondaryColor,
}: TwoToneColorPaletteSetter) {
twoToneColorPalette.primaryColor = primaryColor;
twoToneColorPalette.secondaryColor =
secondaryColor || getSecondaryColor(primaryColor);
}
...restProps
} = props;

static getTwoToneColors(): TwoToneColorPalette {
return {
...twoToneColorPalette,
let colors: TwoToneColorPalette = twoToneColorPalette;
if (primaryColor) {
colors = {
primaryColor,
secondaryColor: secondaryColor || getSecondaryColor(primaryColor),
};
}

render() {
const {
icon,
className,
onClick,
style,
primaryColor,
secondaryColor,
...restProps
} = this.props;

let colors: TwoToneColorPalette = twoToneColorPalette;
if (primaryColor) {
colors = {
primaryColor,
secondaryColor: secondaryColor || getSecondaryColor(primaryColor),
};
}
useInsertStyles();

log(
!isIconDefinition(icon),
`icon should be icon definiton, but got ${icon}`,
);
log(
!isIconDefinition(icon),
`icon should be icon definiton, but got ${icon}`,
);

if (!isIconDefinition(icon)) {
return null;
}
if (!isIconDefinition(icon)) {
return null;
}

let target = icon;
if (target && typeof target.icon === 'function') {
target = {
...target,
icon: target.icon(colors.primaryColor, colors.secondaryColor),
};
}
return generate(target.icon as AbstractNode, `svg-${target.name}`, {
className,
onClick,
style,
'data-icon': target.name,
width: '1em',
height: '1em',
fill: 'currentColor',
'aria-hidden': 'true',
...restProps,
});
let target = icon;
if (target && typeof target.icon === 'function') {
target = {
...target,
icon: target.icon(colors.primaryColor, colors.secondaryColor),
};
}
return generate(target.icon as AbstractNode, `svg-${target.name}`, {
className,
onClick,
style,
'data-icon': target.name,
width: '1em',
height: '1em',
fill: 'currentColor',
'aria-hidden': 'true',
...restProps,
});
}

export default Icon;
IconBase.displayName = 'IconReact';
IconBase.getTwoToneColors = getTwoToneColors;
IconBase.setTwoToneColors = setTwoToneColors;

export default IconBase;
10 changes: 0 additions & 10 deletions packages/icons-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
import { insertCss } from 'insert-css';
import { iconStyles } from './utils';

let cssInjectedFlag = false;

if (!cssInjectedFlag) {
insertCss(iconStyles);
cssInjectedFlag = true;
}

export * from './icons';
export * from './components/twoTonePrimaryColor';
export { default as createFromIconfontCN } from './components/IconFont';
Expand Down
14 changes: 13 additions & 1 deletion packages/icons-react/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AbstractNode, IconDefinition } from '@ant-design/icons-svg/lib/types';
import { generate as generateColor } from '@ant-design/colors';
import React from 'react';
import React, { useEffect } from 'react';
import warning from 'rc-util/lib/warning';
import { insertCss } from 'insert-css';

export function log(valid: boolean, message: string) {
warning(valid, `[@ant-design/icons] ${message}`);
Expand Down Expand Up @@ -128,3 +129,14 @@ export const iconStyles = `
}
}
`;

let cssInjectedFlag = false;

export const useInsertStyles = (styleStr: string = iconStyles) => {
useEffect(() => {
if (!cssInjectedFlag) {
insertCss(styleStr);
cssInjectedFlag = true;
}
}, []);
}

0 comments on commit a7d8906

Please sign in to comment.