mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 12:39:49 +08:00
new icon display
This commit is contained in:
parent
2600d8a4ca
commit
2a54d80639
@ -11,35 +11,11 @@ Semantic vector graphics.
|
||||
|
||||
> Click the icon and copy the code.
|
||||
|
||||
### Directional Icons
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="direction" />, mountNode);
|
||||
import IconDisplay from 'site/theme/template/IconDisplay';
|
||||
ReactDOM.render(<IconDisplay />, mountNode);
|
||||
```
|
||||
|
||||
### Suggested Icons
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="suggestion" />, mountNode);
|
||||
```
|
||||
|
||||
### Application Icons
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="other" />, mountNode);
|
||||
```
|
||||
|
||||
### Brand and Logos
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="logo" />, mountNode);
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Icon
|
||||
|
@ -16,32 +16,9 @@ toc: false
|
||||
|
||||
> 点击图标即可复制代码。
|
||||
|
||||
### 方向性图标
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="direction" />, mountNode);
|
||||
```
|
||||
|
||||
### 提示建议性图标
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="suggestion" />, mountNode);
|
||||
```
|
||||
|
||||
### 网站通用图标
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="other" />, mountNode);
|
||||
```
|
||||
|
||||
### 品牌与标识
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
ReactDOM.render(<IconSet className="icons" catigory="logo" />, mountNode);
|
||||
import IconDisplay from 'site/theme/template/IconDisplay';
|
||||
ReactDOM.render(<IconDisplay />, mountNode);
|
||||
```
|
||||
|
||||
## API
|
||||
|
@ -95,6 +95,7 @@
|
||||
"@types/prop-types": "^15.5.4",
|
||||
"@types/react": "^16.0.0",
|
||||
"@types/react-dom": "^16.0.0",
|
||||
"@types/react-intl": "^2.3.10",
|
||||
"@types/react-slick": "^0.23.2",
|
||||
"@yesmeck/offline-plugin": "^5.0.5",
|
||||
"ansi-styles": "^3.2.0",
|
||||
|
@ -88,5 +88,10 @@ module.exports = {
|
||||
'app.publish.old-version-guide': 'If you need documentation of older version, please visit ',
|
||||
'app.publish.old-version-tips': ', or switch version with the select at header navigation.',
|
||||
'app.docs.color.pick-primary': 'Pick your primary color',
|
||||
'app.docs.components.icon.pick-theme': 'Select the Icon Theme',
|
||||
'app.docs.components.icon.category.direction': 'Directional Icons',
|
||||
'app.docs.components.icon.category.suggestion': 'Suggested Icons',
|
||||
'app.docs.components.icon.category.other': 'Application Icons',
|
||||
'app.docs.components.icon.category.logo': 'Brand and Logos',
|
||||
},
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
ul.anticons-list {
|
||||
margin: 40px 0;
|
||||
margin: 10px 0;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
li {
|
||||
|
60
site/theme/template/IconDisplay/Category.tsx
Normal file
60
site/theme/template/IconDisplay/Category.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import * as React from 'react';
|
||||
import { ThemeType } from '../../../../components/icon';
|
||||
import CopyableIcon from './CopyableIcon';
|
||||
import { injectIntl, InjectedIntlProps } from 'react-intl';
|
||||
import { CategoriesKeys } from './fields';
|
||||
|
||||
interface CategoryProps extends InjectedIntlProps {
|
||||
title: CategoriesKeys;
|
||||
icons: string[];
|
||||
theme: ThemeType;
|
||||
newIcons: string[];
|
||||
}
|
||||
|
||||
interface CategoryState {
|
||||
justCopied: string | null;
|
||||
}
|
||||
|
||||
class Category extends React.Component<CategoryProps, CategoryState> {
|
||||
state = {
|
||||
justCopied: null,
|
||||
};
|
||||
|
||||
onCopied = (type: string) => {
|
||||
this.setState({ justCopied: type }, () => {
|
||||
setTimeout(() => {
|
||||
this.setState({ justCopied: null });
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
icons, title,
|
||||
theme, newIcons,
|
||||
intl: { messages },
|
||||
} = this.props;
|
||||
const items = icons.map((name) => {
|
||||
return (
|
||||
<CopyableIcon
|
||||
key={name}
|
||||
type={name}
|
||||
theme={theme}
|
||||
isNew={newIcons.indexOf(name) >= 0}
|
||||
justCopied={this.state.justCopied}
|
||||
onCopied={this.onCopied}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h3>{messages[`app.docs.components.icon.category.${title}`]}</h3>
|
||||
<ul className={'anticons-list'}>
|
||||
{items}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(Category);
|
34
site/theme/template/IconDisplay/CopyableIcon.tsx
Normal file
34
site/theme/template/IconDisplay/CopyableIcon.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import * as React from 'react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { Icon, Badge } from 'antd';
|
||||
import { ThemeType } from '../../../../components/icon';
|
||||
|
||||
export interface CopyableIconProps {
|
||||
type: string;
|
||||
theme: ThemeType;
|
||||
isNew: boolean;
|
||||
justCopied: string | null;
|
||||
onCopied: (type: string) => any;
|
||||
}
|
||||
|
||||
const CopyableIcon: React.SFC<CopyableIconProps> = ({
|
||||
type, theme, isNew, justCopied, onCopied,
|
||||
}) => {
|
||||
return (
|
||||
<CopyToClipboard
|
||||
text={`<Icon type="${type}" theme="${theme}" />`}
|
||||
onCopy={() => onCopied(type)}
|
||||
>
|
||||
<li className={justCopied === type ? 'copied' : ''}>
|
||||
<Icon type={type} theme={theme} />
|
||||
<span className="anticon-class">
|
||||
<Badge dot={isNew}>
|
||||
{type}
|
||||
</Badge>
|
||||
</span>
|
||||
</li>
|
||||
</CopyToClipboard>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyableIcon;
|
80
site/theme/template/IconDisplay/fields.ts
Normal file
80
site/theme/template/IconDisplay/fields.ts
Normal file
@ -0,0 +1,80 @@
|
||||
export const categories = {
|
||||
direction: [
|
||||
'step-backward', 'step-forward', 'fast-backward',
|
||||
'fast-forward', 'shrink', 'arrows-alt', 'down', 'up', 'left',
|
||||
'right', 'caret-up', 'caret-down', 'caret-left', 'caret-right',
|
||||
'up-circle', 'down-circle', 'left-circle', 'right-circle',
|
||||
'double-right', 'double-left', 'verticle-left', 'verticle-right',
|
||||
'forward', 'backward', 'rollback', 'enter', 'retweet',
|
||||
'swap', 'swap-left', 'swap-right', 'arrow-up', 'arrow-down',
|
||||
'arrow-left', 'arrow-right', 'play-circle',
|
||||
'up-square', 'down-square', 'left-square', 'right-square',
|
||||
'login', 'logout', 'menu-fold', 'menu-unfold',
|
||||
],
|
||||
suggestion: [
|
||||
'question', 'question-circle',
|
||||
'plus', 'plus-circle', 'pause',
|
||||
'pause-circle', 'minus',
|
||||
'minus-circle', 'plus-square', 'minus-square',
|
||||
'info', 'info-circle',
|
||||
'exclamation', 'exclamation-circle',
|
||||
'close', 'close-circle', 'close-square',
|
||||
'check', 'check-circle',
|
||||
'check-square',
|
||||
'clock-circle', 'warning',
|
||||
],
|
||||
other: [
|
||||
'lock', 'unlock', 'area-chart', 'pie-chart', 'bar-chart',
|
||||
'dot-chart', 'bars', 'book', 'calendar', 'cloud', 'cloud-download',
|
||||
'code', 'copy', 'credit-card', 'delete', 'desktop',
|
||||
'download', 'edit', 'ellipsis', 'file', 'file-text',
|
||||
'file-unknown', 'file-pdf', 'file-word', 'file-excel',
|
||||
'file-jpg', 'file-ppt', 'file-markdown', 'file-add',
|
||||
'folder', 'folder-open', 'folder-add', 'hdd', 'frown',
|
||||
'meh', 'smile', 'inbox',
|
||||
'laptop', 'appstore', 'line-chart', 'link',
|
||||
'mail', 'mobile', 'notification', 'paper-clip', 'picture',
|
||||
'poweroff', 'reload', 'search', 'setting', 'share-alt',
|
||||
'shopping-cart', 'tablet', 'tag', 'tags',
|
||||
'to-top', 'upload', 'user', 'video-camera',
|
||||
'home', 'loading', 'loading-3-quarters',
|
||||
'cloud-upload',
|
||||
'star', 'heart', 'environment',
|
||||
'eye', 'camera', 'save', 'team',
|
||||
'solution', 'phone', 'filter', 'exception', 'export',
|
||||
'customer-service', 'qrcode', 'scan', 'like',
|
||||
'dislike', 'message', 'pay-circle',
|
||||
'calculator', 'pushpin',
|
||||
'bulb', 'select', 'switcher', 'rocket', 'bell', 'disconnect',
|
||||
'database', 'compass', 'barcode', 'hourglass', 'key',
|
||||
'flag', 'layout', 'printer', 'sound', 'usb', 'skin', 'tool',
|
||||
'sync', 'wifi', 'car', 'schedule', 'user-add', 'user-delete',
|
||||
'usergroup-add', 'usergroup-delete', 'man', 'woman', 'shop',
|
||||
'gift', 'idcard', 'medicine-box', 'red-envelope', 'coffee',
|
||||
'copyright', 'trademark', 'safety', 'wallet', 'bank', 'trophy',
|
||||
'contacts', 'global', 'shake', 'api', 'fork', 'dashboard', 'form',
|
||||
'table', 'profile',
|
||||
],
|
||||
logo: [
|
||||
'android', 'apple', 'windows',
|
||||
'ie', 'chrome', 'github', 'aliwangwang',
|
||||
'dingding',
|
||||
'weibo-square', 'weibo-circle', 'taobao-circle', 'html5',
|
||||
'weibo', 'twitter', 'wechat', 'youtube', 'alipay-circle',
|
||||
'taobao', 'skype', 'qq', 'medium-workmark', 'gitlab', 'medium',
|
||||
'linkedin', 'google-plus', 'dropbox', 'facebook', 'codepen',
|
||||
'amazon', 'google', 'codepen-circle', 'alipay', 'ant-design',
|
||||
'aliyun', 'zhihu', 'slack', 'slack-square', 'behance',
|
||||
'behance-square', 'dribbble', 'dribbble-square',
|
||||
'instagram', 'yuque',
|
||||
],
|
||||
};
|
||||
|
||||
export interface Categories {
|
||||
direction: string[];
|
||||
suggestion: string[];
|
||||
other: string[];
|
||||
logo: string[];
|
||||
}
|
||||
|
||||
export type CategoriesKeys = keyof Categories;
|
@ -1,21 +1,90 @@
|
||||
import * as React from 'react';
|
||||
import { ThemeType } from '../../../../components/icon';
|
||||
import manifest from '@ant-design/icons/lib/manifest';
|
||||
import { Manifest, ThemeType as ThemeFolderType } from '@ant-design/icons/lib/types';
|
||||
import Category from './Category';
|
||||
import { Radio, Icon } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib/radio/interface';
|
||||
import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons';
|
||||
import { categories, Categories, CategoriesKeys } from './fields';
|
||||
import { injectIntl, InjectedIntlProps } from 'react-intl';
|
||||
|
||||
interface IconDisplayProps {
|
||||
icons: Array<{ category: string, names: string[] }>;
|
||||
interface IconDisplayProps extends InjectedIntlProps {
|
||||
}
|
||||
|
||||
interface IconDisplayState {
|
||||
theme: ThemeType;
|
||||
}
|
||||
|
||||
export default class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
|
||||
class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
|
||||
|
||||
static cagetories: Categories = categories;
|
||||
|
||||
static newIconNames: string[] = [];
|
||||
|
||||
static themeTypeMapper: { [key: string]: ThemeFolderType } = {
|
||||
filled: 'fill',
|
||||
outlined: 'outline',
|
||||
twoTone: 'twotone',
|
||||
};
|
||||
|
||||
state: IconDisplayState = {
|
||||
theme: 'outlined',
|
||||
};
|
||||
|
||||
getComputedDisplayList() {
|
||||
return Object.keys(IconDisplay.cagetories)
|
||||
.map(
|
||||
(category: CategoriesKeys) => ({
|
||||
category,
|
||||
icons: IconDisplay.cagetories[category]
|
||||
.filter((name) => manifest[IconDisplay.themeTypeMapper[this.state.theme]].indexOf(name) !== -1),
|
||||
}),
|
||||
)
|
||||
.filter(({ icons }) => Boolean(icons.length));
|
||||
}
|
||||
|
||||
handleChangeTheme = (e: RadioChangeEvent) => {
|
||||
this.setState({
|
||||
theme: e.target.value as ThemeType,
|
||||
});
|
||||
}
|
||||
|
||||
renderCategories(list: Array<{ category: string, icons: string[] }>) {
|
||||
return list.map(({ category, icons }) => {
|
||||
return (
|
||||
<Category
|
||||
key={category}
|
||||
title={category}
|
||||
icons={icons}
|
||||
theme={this.state.theme}
|
||||
newIcons={IconDisplay.newIconNames}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
// wip
|
||||
return null;
|
||||
const { intl: { messages } } = this.props;
|
||||
const list = this.getComputedDisplayList();
|
||||
return (
|
||||
<div>
|
||||
<h3>{messages['app.docs.components.icon.pick-theme']}</h3>
|
||||
<Radio.Group value={this.state.theme} onChange={this.handleChangeTheme}>
|
||||
<Radio.Button value="filled">
|
||||
<Icon component={FilledIcon} /> Filled
|
||||
</Radio.Button>
|
||||
<Radio.Button value="outlined">
|
||||
<Icon component={OutlinedIcon} /> Outlined
|
||||
</Radio.Button>
|
||||
<Radio.Button value="twoTone">
|
||||
<Icon component={TwoToneIcon} /> Two Tone
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
{this.renderCategories(list)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(IconDisplay);
|
||||
|
46
site/theme/template/IconDisplay/themeIcons.tsx
Normal file
46
site/theme/template/IconDisplay/themeIcons.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export const FilledIcon: React.SFC = (props: any) => {
|
||||
const path = 'M864 64H160C107 64 64 107 64 160v' +
|
||||
'704c0 53 43 96 96 96h704c53 0 96-43 96-96V16' +
|
||||
'0c0-53-43-96-96-96z';
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
viewBox="0 0 1024 1024"
|
||||
>
|
||||
<path d={path} />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const OutlinedIcon: React.SFC = (props: any) => {
|
||||
const path = 'M864 64H160C107 64 64 107 64 160v7' +
|
||||
'04c0 53 43 96 96 96h704c53 0 96-43 96-96V160c' +
|
||||
'0-53-43-96-96-96z m-12 800H172c-6.6 0-12-5.4-' +
|
||||
'12-12V172c0-6.6 5.4-12 12-12h680c6.6 0 12 5.4' +
|
||||
' 12 12v680c0 6.6-5.4 12-12 12z';
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
viewBox="0 0 1024 1024"
|
||||
>
|
||||
<path d={path} />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const TwoToneIcon: React.SFC = (props: any) => {
|
||||
const path = 'M16 512c0 273.932 222.066 496 496 49' +
|
||||
'6s496-222.068 496-496S785.932 16 512 16 16 238.' +
|
||||
'066 16 512z m496 368V144c203.41 0 368 164.622 3' +
|
||||
'68 368 0 203.41-164.622 368-368 368z';
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
viewBox="0 0 1024 1024"
|
||||
>
|
||||
<path d={path} />
|
||||
</svg>
|
||||
);
|
||||
};
|
@ -88,5 +88,10 @@ module.exports = {
|
||||
'app.publish.old-version-guide': '如果您还需要使用旧版,请查阅 ',
|
||||
'app.publish.old-version-tips': ',也可通过页面右上角的文档版本选择框进行切换。',
|
||||
'app.docs.color.pick-primary': '选择你的主色',
|
||||
'app.docs.components.icon.pick-theme': '选择图标主题风格',
|
||||
'app.docs.components.icon.category.direction': '方向性图标',
|
||||
'app.docs.components.icon.category.suggestion': '提示建议性图标',
|
||||
'app.docs.components.icon.category.other': '网站通用图标',
|
||||
'app.docs.components.icon.category.logo': '品牌和标识',
|
||||
},
|
||||
};
|
||||
|
2
typings/custom-typings.d.ts
vendored
2
typings/custom-typings.d.ts
vendored
@ -100,3 +100,5 @@ declare module 'intersperse';
|
||||
declare module "raf";
|
||||
|
||||
declare module "react-lifecycles-compat";
|
||||
|
||||
declare module "react-copy-to-clipboard";
|
||||
|
Loading…
Reference in New Issue
Block a user