From 2a54d806394e17b515eb10731c962dc596960208 Mon Sep 17 00:00:00 2001 From: HeskeyBaozi Date: Sat, 1 Sep 2018 16:16:11 +0800 Subject: [PATCH] new icon display --- components/icon/index.en-US.md | 28 +------ components/icon/index.zh-CN.md | 27 +------ package.json | 1 + site/theme/en-US.js | 5 ++ site/theme/static/icons.less | 2 +- site/theme/template/IconDisplay/Category.tsx | 60 ++++++++++++++ .../template/IconDisplay/CopyableIcon.tsx | 34 ++++++++ site/theme/template/IconDisplay/fields.ts | 80 +++++++++++++++++++ site/theme/template/IconDisplay/index.tsx | 79 ++++++++++++++++-- .../theme/template/IconDisplay/themeIcons.tsx | 46 +++++++++++ site/theme/zh-CN.js | 5 ++ typings/custom-typings.d.ts | 2 + 12 files changed, 312 insertions(+), 57 deletions(-) create mode 100644 site/theme/template/IconDisplay/Category.tsx create mode 100644 site/theme/template/IconDisplay/CopyableIcon.tsx create mode 100644 site/theme/template/IconDisplay/fields.ts create mode 100644 site/theme/template/IconDisplay/themeIcons.tsx diff --git a/components/icon/index.en-US.md b/components/icon/index.en-US.md index ffa57a262c..26eb6a834d 100644 --- a/components/icon/index.en-US.md +++ b/components/icon/index.en-US.md @@ -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(, mountNode); -``` - -### Suggested Icons - -```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); -``` - -### Application Icons - ```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); +import IconDisplay from 'site/theme/template/IconDisplay'; +ReactDOM.render(, mountNode); ``` -### Brand and Logos - -```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); -``` - - ## API ### Icon diff --git a/components/icon/index.zh-CN.md b/components/icon/index.zh-CN.md index 31ad77a51d..e42348b3a8 100644 --- a/components/icon/index.zh-CN.md +++ b/components/icon/index.zh-CN.md @@ -16,32 +16,9 @@ toc: false > 点击图标即可复制代码。 -### 方向性图标 - -```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); -``` - -### 提示建议性图标 - -```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); -``` - -### 网站通用图标 - -```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); -``` - -### 品牌与标识 - ```__react -import IconSet from 'site/theme/template/IconSet'; -ReactDOM.render(, mountNode); +import IconDisplay from 'site/theme/template/IconDisplay'; +ReactDOM.render(, mountNode); ``` ## API diff --git a/package.json b/package.json index 03c490eb1a..0d362052ef 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/site/theme/en-US.js b/site/theme/en-US.js index 789b54a25d..16f53f9286 100644 --- a/site/theme/en-US.js +++ b/site/theme/en-US.js @@ -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', }, }; diff --git a/site/theme/static/icons.less b/site/theme/static/icons.less index 905fee80fb..c7fe863744 100644 --- a/site/theme/static/icons.less +++ b/site/theme/static/icons.less @@ -1,5 +1,5 @@ ul.anticons-list { - margin: 40px 0; + margin: 10px 0; list-style: none; overflow: hidden; li { diff --git a/site/theme/template/IconDisplay/Category.tsx b/site/theme/template/IconDisplay/Category.tsx new file mode 100644 index 0000000000..21e7d8e32f --- /dev/null +++ b/site/theme/template/IconDisplay/Category.tsx @@ -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 { + 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 ( + = 0} + justCopied={this.state.justCopied} + onCopied={this.onCopied} + /> + ); + }); + return ( +
+

{messages[`app.docs.components.icon.category.${title}`]}

+
    + {items} +
+
+ ); + } +} + +export default injectIntl(Category); diff --git a/site/theme/template/IconDisplay/CopyableIcon.tsx b/site/theme/template/IconDisplay/CopyableIcon.tsx new file mode 100644 index 0000000000..57d057317d --- /dev/null +++ b/site/theme/template/IconDisplay/CopyableIcon.tsx @@ -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 = ({ + type, theme, isNew, justCopied, onCopied, +}) => { + return ( + `} + onCopy={() => onCopied(type)} + > +
  • + + + + {type} + + +
  • +
    + ); +}; + +export default CopyableIcon; diff --git a/site/theme/template/IconDisplay/fields.ts b/site/theme/template/IconDisplay/fields.ts new file mode 100644 index 0000000000..f7f07ddf03 --- /dev/null +++ b/site/theme/template/IconDisplay/fields.ts @@ -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; diff --git a/site/theme/template/IconDisplay/index.tsx b/site/theme/template/IconDisplay/index.tsx index 6ce36c22d9..abb29c22fb 100644 --- a/site/theme/template/IconDisplay/index.tsx +++ b/site/theme/template/IconDisplay/index.tsx @@ -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 { +class IconDisplay extends React.Component { + + 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 ( + + ); + }); + } + render() { - // wip - return null; + const { intl: { messages } } = this.props; + const list = this.getComputedDisplayList(); + return ( +
    +

    {messages['app.docs.components.icon.pick-theme']}

    + + + Filled + + + Outlined + + + Two Tone + + + {this.renderCategories(list)} +
    + ); } } + +export default injectIntl(IconDisplay); diff --git a/site/theme/template/IconDisplay/themeIcons.tsx b/site/theme/template/IconDisplay/themeIcons.tsx new file mode 100644 index 0000000000..8d908d4769 --- /dev/null +++ b/site/theme/template/IconDisplay/themeIcons.tsx @@ -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 ( + + + + ); +}; + +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 ( + + + + ); +}; + +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 ( + + + + ); +}; diff --git a/site/theme/zh-CN.js b/site/theme/zh-CN.js index 7333ae851d..fc5c839198 100644 --- a/site/theme/zh-CN.js +++ b/site/theme/zh-CN.js @@ -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': '品牌和标识', }, }; diff --git a/typings/custom-typings.d.ts b/typings/custom-typings.d.ts index 7993d2face..28d17bf8c4 100644 --- a/typings/custom-typings.d.ts +++ b/typings/custom-typings.d.ts @@ -100,3 +100,5 @@ declare module 'intersperse'; declare module "raf"; declare module "react-lifecycles-compat"; + +declare module "react-copy-to-clipboard";