From 8c6a3af39d2725527e8f70ee99f9e88199702992 Mon Sep 17 00:00:00 2001 From: aboutblank Date: Wed, 8 May 2019 15:36:17 +0800 Subject: [PATCH] fix(Menu),docs(*): add theme docs, close #629 (#634) * docs(*): add theme docs, close #629 * fix(Menu): empty focus key when blur using undefined --- README.zh-cn.md | 77 +++++++++++--------- site/zh-cn/theme.md | 159 ++++++++++++++++++++++++----------------- src/menu/view/menu.jsx | 2 +- 3 files changed, 139 insertions(+), 99 deletions(-) diff --git a/README.zh-cn.md b/README.zh-cn.md index 96f89ab43b..84e2f4379a 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -1,11 +1,11 @@ [English](./README.md) | 简体中文 +

Fusion

-

一套企业级中后台UI的解决方案,致力于解决设计师与前端在工作协同、产品体验一致性、开发效率方面的问题

--- @@ -19,11 +19,10 @@

-你可以通过[一站式协作平台](https://fusion.design)灵活地定制自己的DesignSystem,生成设计物料与代码分片到设计师的工具端 [FusionCool](https://fusion.design/tool?from=github) 及开发者的工具端 [Iceworks](https://fusion.design/tool?from=github),同时保证代码和视觉稿之间的一致性 +你可以通过[一站式协作平台](https://fusion.design)灵活地定制自己的 DesignSystem,生成设计物料与代码分片到设计师的工具端 [FusionCool](https://fusion.design/tool?from=github) 及开发者的工具端 [Iceworks](https://fusion.design/tool?from=github),同时保证代码和视觉稿之间的一致性 ![howtouse](https://img.alicdn.com/tfs/TB1dF3BH4TpK1RjSZFMXXbG_VXa-1280-720.gif) - # 🤔 为什么用 `@alifd/next` 配合 [Fusion Design](https://fusion.design) 解决在页面开发时设计师和前端协同的问题。通过这套体系设计师可以自由的定制组件的 UI 并产出一个 npm 主题包,前端可以直接使用这个主题包不需要关注组件的还原度问题。省去了和设计师反复的去做还原度 Review 的工作量,大幅度的提高了开发效率。 @@ -32,11 +31,9 @@ # 💻 浏览器支持 -![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![UC](https://raw.github.com/alrra/browser-logos/master/src/uc/uc_48x48.png) -:---: | :---: | :---: | :---: | :---: | :---: | :---: - ✔ | ✔ | ✔ | 9+ ✔ | ✔ | ✔ | ✔ - - +| ![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![UC](https://raw.github.com/alrra/browser-logos/master/src/uc/uc_48x48.png) | +| :--------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------: | :--------------------------------------------------------------------------: | +| ✔ | ✔ | ✔ | 9+ ✔ | ✔ | ✔ | ✔ | # 🚀 快速开始 @@ -52,12 +49,13 @@ npm install @alifd/next --save 在浏览器中使用 script 和 link 标签直接引入文件,并使用全局变量 Next。我们在 npm 包中提供了 `@alifd/next/dist` 目录下的 next.js/next.min.js 和 next.css/next.min.css 等文件,也可以通过 [unpkg](https://unpkg.com/@alifd/next/dist/) 进行下载。 -``` html - +```html + -// 以上引入都是引入的最新版本 @alifd/next ,但我们推荐引入固定版本的next组件,以保证代码稳定 +// 以上引入都是引入的最新版本 @alifd/next +,但我们推荐引入固定版本的next组件,以保证代码稳定 // 或作为自己的静态资源引入 @@ -66,68 +64,79 @@ npm install @alifd/next --save ## ☔️ 依赖 -* `@alifd/next` 基于 `react@16` 开发,目前并不兼容 `react@16` 以下的版本,且将 react/react-dom 作为 peerDependencies,需要用户手动提前安装或引入。 -* `@alifd/next` 在处理日期时间相关组件逻辑时,使用了 [moment](https://github.com/moment/moment) 库,且将 moment 作为 peerDependencies,需要用户手动提前安装或引入。 +- `@alifd/next` 基于 `react@16` 开发,目前并不兼容 `react@16` 以下的版本,且将 react/react-dom 作为 peerDependencies,需要用户手动提前安装或引入。 +- `@alifd/next` 在处理日期时间相关组件逻辑时,使用了 [moment](https://github.com/moment/moment) 库,且将 moment 作为 peerDependencies,需要用户手动提前安装或引入。 ## 🎯 引入 ### 全量引入 - -``` js -import '@alifd/next/dist/next.css'; -// import '@alifd/next/index.scss'; +```js +// 全量引入压缩后的next基础样式 +import '@alifd/next/dist/next.min.css'; import { Button, Input } from '@alifd/next'; ``` -### 按需引入 +- 优点:使用简单, 样式无需编译直接使用 +- 缺点:当前页面未使用的组件也会被打包 +**Note:** 如果引入 scss 版本的样式,`import '@alifd/next/index.scss';`,在 webpack 打包时请使用`fast-sass-loader`,否则编译出来的样式文件可能会很大。 +原因是`@alifd/next`内部,组件之间存在依赖关系,例如 Icon 组件被 Menu 组件依赖。对于 webpack 来讲,在分析依赖阶段,Menu 的 index.scss 和 Icon 的 index.scss 是两个不同的模块,两个文件会独立的在 sass-loader 阶段编译。因此 Icon 的 sass 会被重复编译。使用`fast-sass-loader`可以避免样式重复打包的问题。 + +### 按需引入 #### 1.手动引入 -``` js +```js import Button from '@alifd/next/lib/button'; import '@alifd/next/lib/button/style'; ``` +- 优点:按需引入 js 代码、样式代码,不会加载不必要的组件 +- 缺点:使用起来过于繁琐,需要手动添加每一个用到的组件 js 代码及样式 + #### 2.使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) (推荐) -但大多数人更习惯的写法如下: +通过 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 插件,可以将下面的代码 -``` js +```js import { Button } from '@alifd/next'; ``` -通过 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 插件,可以将上述代码转化为类似下面的代码: +转化为类似下面的代码: -``` js +```js import Button from '@alifd/next/lib/button'; import '@alifd/next/lib/button/style'; ``` -babel配置: -``` js +babel 配置: + +```js // webpack babel loader option or .babelrc { - // ... - plugins: [ - ['babel-plugin-import', { - libraryName: '@alifd/next', - style: true - }] - ] + // ... + plugins: [ + [ + 'babel-plugin-import', + { + libraryName: '@alifd/next', + style: true, + }, + ], + ]; } ``` - - ## 🔗 高级用法 + - [使用主题包](./site/zh-cn/theme.md) - [国际化](./site/zh-cn/i18n.md) - [字体文件私有化部署](./site/zh-cn/font-deploy.md) ## 🌈 贡献代码 + - [贡献代码](./site/zh-cn/contributing.md) ## 📣 加入社区 diff --git a/site/zh-cn/theme.md b/site/zh-cn/theme.md index 5ff1e155f5..50ed9f734c 100644 --- a/site/zh-cn/theme.md +++ b/site/zh-cn/theme.md @@ -1,6 +1,13 @@ # 使用主题包 -如果默认的组件主题样式无法满足你的视觉需求,那么你可以通过 Fusion Design 提供的强大的样式配置能力配置自定义的主题样式包。该主题包(包名例如取 `@alifd/theme-xxx` )可以在平台上导出发布至npm,它的本质是一个 scss 变量包,配合`@alifd/next`共同使用。 +如果默认的组件主题样式无法满足你的视觉需求,那么你可以通过 Fusion Design 提供的强大的样式配置能力配置自定义的主题样式包。该主题包(包名例如取 `@alifd/theme-xxx` )可以在平台上导出发布至 npm,它的本质是一个 scss 变量包,配合`@alifd/next`共同使用。 + +**Note:** 使用主题包时,请务必保证 “项目依赖的 next 组件版本” 与 “主题包依赖的 next 组件版本” 一致(至少到 minor 版本一致),以防止 js/css 因版本不匹配导致的潜在问题 + +- 项目依赖的 next 组件版本:node_modules 中,项目真正使用的版本 +- 主题包依赖的 next 组件版本:查看发布的主题包 package.json 的 dependencies 中`@alifd/next`的版本,例如 https://unpkg.com/@alifd/theme-1/package.json + +如果不匹配(minor 不同),请去往[配置平台](https://fusion.design/)发布主题。 ## 安装 @@ -12,81 +19,105 @@ npm install @alifd/theme-xxx --save ### 全量引入 -``` js -import '@alifd/theme-xxx/index.scss'; - +```js +// 直接使用主题包中预编译生成的 css 文件 +import '@alifd/theme-xxx/dist/next.css'; import { Button, Input } from '@alifd/next'; ``` -**Note:** 如果你使用的是主题包中预编译生成的 css 文件,请保证 “项目依赖的next组件版本” 与 “主题包依赖的next组件版本” 一致,以防止 js/css 因版本不匹配导致的潜在问题 - ### 按需引入 + 除使用在《快速开始》一节中提到的 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 外,还需搭配 [@alifd/next-theme-loader](https://github.com/alibaba-fusion/next-theme-loader) 和 [@alifd/next-theme-webpack-plugin](https://github.com/alibaba-fusion/next-theme-webpack-plugin),可参考如下 webpack 配置: +@alifd/next-theme-loader 用来处理单个组件的样式问题,@alifd/next-theme-webpack-plugin 用来处理 + +```bash +npm install @alifd/next-theme-webpack-plugin fast-sass-loader @alifd/next-theme-loader +``` -``` js +```js const path = require('path'); const webpack = require('webpack'); const ThemePlugin = require('@alifd/next-theme-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { - entry: { - index: './src/index.jsx' - }, - output: { - path: path.join(__dirname, 'build'), - filename: '[name].js' - }, - resolve: { - extensions: ['.js', '.jsx'] - }, - devtool: 'inline-source-map', - module: { - rules: [{ - test: /\.jsx?$/, - use: { - loader: 'babel-loader', - options: { - presets: [ - 'env', - 'react', - 'stage-0' - ], - plugins: [ - 'add-module-exports', - 'transform-decorators-legacy', - ['babel-plugin-import', { style: true }] - ] - } - }, - exclude: /node_modules/ - }, { - test: /\.css$/, - use: ExtractTextPlugin.extract({ - use: 'css-loader' - }) - }, { - test: /\.scss$/, - use: ExtractTextPlugin.extract({ - use: [ - 'css-loader', - 'fast-sass-loader', - { - // 添加 @alifd/next-theme-loader,引入自定义主题样式对应的 scss 变量 - loader: '@alifd/next-theme-loader', - options: { - theme: '@alifd/theme-xxx' - } - } - ] - }) - }] - }, - plugins: [ - // 添加 @alifd/next-theme-webpack-plugin,引入 normalize 样式以及自定义 icon 定义 - new ThemePlugin({ theme: '@alifd/theme-xxx' }), - new ExtractTextPlugin('[name].css') - ] + entry: { + index: './src/index.jsx', + }, + output: { + path: path.join(__dirname, 'build'), + filename: '[name].js', + }, + resolve: { + extensions: ['.js', '.jsx'], + }, + devtool: 'inline-source-map', + module: { + rules: [ + { + test: /\.jsx?$/, + use: { + loader: 'babel-loader', + options: { + presets: ['env', 'react', 'stage-0'], + plugins: [ + 'add-module-exports', + 'transform-decorators-legacy', + ['babel-plugin-import', { style: true }], + ], + }, + }, + exclude: /node_modules/, + }, + { + test: /\.css$/, + use: ExtractTextPlugin.extract({ + use: 'css-loader', + }), + }, + { + test: /\.scss$/, + use: ExtractTextPlugin.extract({ + use: [ + 'css-loader', + 'fast-sass-loader', + { + // 添加 @alifd/next-theme-loader,引入自定义主题样式对应的 scss 变量 + loader: '@alifd/next-theme-loader', + options: { + theme: '@alifd/theme-xxx', + // 基准包,默认是@alifd/next + base: '@alifd/next', + // 注入变量,来编译组件样式 + // 支持 Object 和 String , 如果是 String 请写绝对路径 例如: modifyVars: path.join(__dirname, 'variable.scss') + // 以下为Object + modifyVars: { + '$css-prefix': '"myprefix-"', + }, + }, + }, + ], + }), + }, + ], + }, + plugins: [ + // 添加 @alifd/next-theme-webpack-plugin,引入 normalize 样式以及自定义 icon 定义 + new ThemePlugin({ + theme: '@alifd/theme-xxx', + // 基准包,默认是@alifd/next + libraryName: '@alifd/next', + // 是否将内置的normalize样式添加到最终的样式包中,默认为true + prependNormalizeCSS: true, + // 注入变量,来编译normalize和icon样式 + // 支持 Object 和 String , 如果是 String 请写绝对路径 例如: modifyVars: path.join(__dirname, 'variable.scss') + // 以下为Object + modifyVars: { + '$css-prefix': '"myprefix-"', + }, + }), + new ExtractTextPlugin('[name].css'), + ], }; ``` diff --git a/src/menu/view/menu.jsx b/src/menu/view/menu.jsx index 60ca68c22c..06881c00ae 100644 --- a/src/menu/view/menu.jsx +++ b/src/menu/view/menu.jsx @@ -270,7 +270,7 @@ export default class Menu extends Component { onBlur(e) { this.setState({ - focusedKey: '', + focusedKey: undefined, }); this.props.onBlur && this.props.onBlur(e);