浏览代码

feat: init

伍浩威 4 年之前
当前提交
f76bd5879d
共有 100 个文件被更改,包括 37561 次插入0 次删除
  1. 7 0
      .commitlintrc.js
  2. 15 0
      .eslintignore
  3. 69 0
      .eslintrc.js
  4. 229 0
      .gitignore
  5. 3 0
      .npmrc
  6. 10 0
      .prettierrc.js
  7. 12 0
      .storybook/animation/react/main.js
  8. 78 0
      .storybook/base/base.js
  9. 12 0
      .storybook/js/main.js
  10. 2 0
      .storybook/preview.js
  11. 9 0
      .storybook/ts/main.js
  12. 71 0
      .storybook/v5config/base/config.js
  13. 82 0
      .storybook/v5config/base/webpack.config.js
  14. 1 0
      .storybook/v5config/js/addons.js
  15. 8 0
      .storybook/v5config/js/config.js
  16. 8 0
      .storybook/v5config/js/webpack.config.js
  17. 1 0
      .storybook/v5config/ts/addons.js
  18. 8 0
      .storybook/v5config/ts/config.js
  19. 8 0
      .storybook/v5config/ts/webpack.config.js
  20. 42 0
      .stylelintrc.js
  21. 74 0
      .vscode/launch.json
  22. 49 0
      .vscode/settings.json
  23. 43 0
      CONTRIBUTING-en-US.md
  24. 46 0
      CONTRIBUTING.md
  25. 21 0
      LICENSE
  26. 99 0
      README-zh-CN.md
  27. 84 0
      README.md
  28. 27 0
      babel.config.js
  29. 338 0
      content/basic/grid/index-en-US.md
  30. 338 0
      content/basic/grid/index.md
  31. 161 0
      content/basic/icon/index-en-US.md
  32. 160 0
      content/basic/icon/index.md
  33. 506 0
      content/basic/layout/index-en-US.md
  34. 520 0
      content/basic/layout/index.md
  35. 179 0
      content/basic/space/index-en-US.md
  36. 177 0
      content/basic/space/index.md
  37. 213 0
      content/basic/tokens/index-en-US.md
  38. 217 0
      content/basic/tokens/index.md
  39. 392 0
      content/basic/typography/index-en-US.md
  40. 376 0
      content/basic/typography/index.md
  41. 188 0
      content/feedback/banner/index-en-US.md
  42. 186 0
      content/feedback/banner/index.md
  43. 320 0
      content/feedback/notification/index-en-US.md
  44. 312 0
      content/feedback/notification/index.md
  45. 153 0
      content/feedback/popconfirm/index-en-US.md
  46. 151 0
      content/feedback/popconfirm/index.md
  47. 240 0
      content/feedback/progress/index-en-US.md
  48. 269 0
      content/feedback/progress/index.md
  49. 387 0
      content/feedback/skeleton/index-en-US.md
  50. 393 0
      content/feedback/skeleton/index.md
  51. 177 0
      content/feedback/spin/index-en-US.md
  52. 152 0
      content/feedback/spin/index.md
  53. 411 0
      content/feedback/toast/index-en-US.md
  54. 413 0
      content/feedback/toast/index.md
  55. 395 0
      content/input/autocomplete/index-en-US.md
  56. 396 0
      content/input/autocomplete/index.md
  57. 532 0
      content/input/button/index-en-US.md
  58. 495 0
      content/input/button/index.md
  59. 1469 0
      content/input/cascader/index-en-US.md
  60. 1453 0
      content/input/cascader/index.md
  61. 428 0
      content/input/checkbox/index-en-US.md
  62. 413 0
      content/input/checkbox/index.md
  63. 823 0
      content/input/datepicker/index-en-US.md
  64. 797 0
      content/input/datepicker/index.md
  65. 1824 0
      content/input/form/index-en-US.md
  66. 2094 0
      content/input/form/index.md
  67. 452 0
      content/input/input/index-en-US.md
  68. 461 0
      content/input/input/index.md
  69. 242 0
      content/input/inputnumber/index-en-US.md
  70. 223 0
      content/input/inputnumber/index.md
  71. 407 0
      content/input/radio/index-en-US.md
  72. 364 0
      content/input/radio/index.md
  73. 182 0
      content/input/rating/index-en-US.md
  74. 159 0
      content/input/rating/index.md
  75. 1415 0
      content/input/select/index-en-US.md
  76. 1452 0
      content/input/select/index.md
  77. 260 0
      content/input/slider/index-en-US.md
  78. 244 0
      content/input/slider/index.md
  79. 189 0
      content/input/switch/index-en-US.md
  80. 188 0
      content/input/switch/index.md
  81. 461 0
      content/input/taginput/index-en-US.md
  82. 460 0
      content/input/taginput/index.md
  83. 331 0
      content/input/timepicker/index-en-US.md
  84. 315 0
      content/input/timepicker/index.md
  85. 946 0
      content/input/transfer/index-en-US.md
  86. 948 0
      content/input/transfer/index.md
  87. 1263 0
      content/input/treeselect/index-en-US.md
  88. 1243 0
      content/input/treeselect/index.md
  89. 1159 0
      content/input/upload/index-en-US.md
  90. 1181 0
      content/input/upload/index.md
  91. 31 0
      content/makeLn.js
  92. 382 0
      content/navigation/anchor/index-en-US.md
  93. 385 0
      content/navigation/anchor/index.md
  94. 88 0
      content/navigation/backtop/index-en-US.md
  95. 87 0
      content/navigation/backtop/index.md
  96. 343 0
      content/navigation/breadcrumb/index-en-US.md
  97. 345 0
      content/navigation/breadcrumb/index.md
  98. 788 0
      content/navigation/navigation/index-en-US.md
  99. 791 0
      content/navigation/navigation/index.md
  100. 210 0
      content/navigation/pagination/index-en-US.md

+ 7 - 0
.commitlintrc.js

@@ -0,0 +1,7 @@
+module.exports = {
+    extends: ['@commitlint/config-conventional'],
+    rules: {
+        'subject-case': [0, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
+        'header-max-length': [0, 'always', 120],
+    },
+};

+ 15 - 0
.eslintignore

@@ -0,0 +1,15 @@
+/build/*.js
+dist/
+/public/*.js
+/output/*.js
+**/adapter.js
+**/*.stories.js
+**/*.test.js
+**/*.d.ts
+**/_story/*.stories.tsx
+**/_story/*.stories.jsx
+packages/semi-theme-default/css/semi.css
+**/css/semi.css
+packages/**/lib/
+packages/**/dist/
+

+ 69 - 0
.eslintrc.js

@@ -0,0 +1,69 @@
+/* eslint-disable */
+module.exports = {
+    env: {
+        'jest/globals': true,
+        'browser': true,
+        'node': true
+    },
+    settings: {
+        react: {
+            "version": "detect"
+        }
+    },
+    overrides: [
+        {
+            files: ['*.js', '*.jsx'],
+            extends: ['jest-enzyme', 'plugin:react/recommended', 'plugin:import/recommended', 'plugin:import/errors', 'plugin:import/warnings'],
+            parser: '@babel/eslint-parser',
+            plugins: ['react', 'react-hooks', 'jest', 'import'],
+            rules: {
+                // 因为历史原因,现有项目基本全部是4个空格
+                indent: ['error', 4, { 'SwitchCase': 1 }],
+                'react/display-name': 'off',
+                'react/jsx-indent': ['error', 4],
+                'react/jsx-indent-props': ['error', 4],
+                'react/prefer-stateless-function': ['warn'],
+                'react/no-find-dom-node': ['warn'],
+                'react/prop-types': 'off',
+                'react/prefer-stateless-function': 'off',
+                'operator-linebreak': ['warn', 'after', { 'overrides': { '?': 'before', ':': 'before' } }],
+                'import/no-unresolved': 'off'
+            },
+            globals: {
+                "sinon": "readonly",
+            },
+        },
+        {
+            files: ['*.ts', '*.tsx'],
+            extends: ['jest-enzyme', 'plugin:@typescript-eslint/recommended', 'plugin:import/typescript', 'plugin:react/recommended'],
+            parser: '@typescript-eslint/parser',
+            parserOptions: {
+                project: ['./tsconfig.eslint.json'],
+            },
+            plugins: ['react', 'jest', 'react-hooks', 'import', '@typescript-eslint'],
+            rules: {
+                // 因为历史原因,现有项目基本全部是4个空格
+                indent: 'off',
+                '@typescript-eslint/indent': ['error', 4],
+                'react/display-name': 'off',
+                'react/jsx-indent': ['error', 4],
+                'react/jsx-indent-props': ['error', 4],
+                'react/prefer-stateless-function': ['warn'],
+                'react/no-find-dom-node': ['warn'],
+                'react/prop-types': 'off',
+                'react-hooks/rules-of-hooks': 'error', 
+                'react-hooks/exhaustive-deps': 'warn',
+                'react/prefer-stateless-function': 'off',
+                '@typescript-eslint/explicit-module-boundary-types': 'off',
+                '@typescript-eslint/explicit-function-return-type': 'off',
+                '@typescript-eslint/no-explicit-any': 'off',
+                '@typescript-eslint/naming-convention': 'off',
+                '@typescript-eslint/ban-ts-comment': 'off',
+                '@typescript-eslint/no-var-requires': 'warn',
+                '@typescript-eslint/no-inferrable-types': 'off',
+                '@typescript-eslint/no-this-alias': 'off',
+                'import/no-unresolved': 'off'
+            }
+        },
+    ],
+};

+ 229 - 0
.gitignore

@@ -0,0 +1,229 @@
+.tpl-temp
+server/log/
+server/view/
+# expo
+.expo/
+
+# json
+static/search_data_client.json
+search/data_client.json
+static/changeLog.json
+static/designToken.json
+
+# dependencies
+/node_modules
+packages/**/node_modules
+
+# output
+.build_temp
+output
+dist
+build
+_site
+packages/**/lib
+packages/semi-theme-default/css/semi.css
+packages/semi-theme-default/semi.scss
+public
+storybook-static/
+*.zip
+
+# misc
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+### Bower ###
+bower_components
+.bower-cache
+.bower-registry
+.bower-tmp
+
+### Git ###
+*.orig
+
+### Linux ###
+*~
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# node-waf configuration
+.lock-wscript
+yarn.lock
+package-lock.json
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# next.js build output
+.next
+
+# nuxt.js build output
+.nuxt
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless
+
+### ReactNative.Gradle Stack ###
+.gradle
+/build/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Cache of project
+.gradletasknamecache
+
+### ReactNative.Buck Stack ###
+buck-out/
+.buckconfig.local
+.buckd/
+.buckversion
+.fakebuckversion
+
+### ReactNative.Android Stack ###
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+gen/
+out/
+
+# Gradle files
+.gradle/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+.idea
+*.iml
+.idea/workspace.xml
+.idea/tasks.xml
+.idea/gradle.xml
+.idea/assetWizardSettings.xml
+.idea/dictionaries
+.idea/libraries
+.idea/caches
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
+
+### SVN ###
+.svn/
+
+### VisualStudioCode ###
+# .vscode/
+
+# metro
+tmp
+
+# test
+/__snapshots__/

+ 3 - 0
.npmrc

@@ -0,0 +1,3 @@
+sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
+phantomjs_cdnurl=https://npm.taobao.org/mirrors/phantomjs/
+electron_mirror=https://npm.taobao.org/mirrors/electron/

+ 10 - 0
.prettierrc.js

@@ -0,0 +1,10 @@
+module.exports = {
+    proseWrap: 'never',
+    printWidth: 120,
+    tabWidth: 4,
+    trailingComma: 'es5',
+    bracketSpacing: true,
+    singleQuote: true,
+    useTabs: false,
+    semi: true,
+};

+ 12 - 0
.storybook/animation/react/main.js

@@ -0,0 +1,12 @@
+const config = require('../../base/base');
+
+module.exports = {
+  ...config,
+  "stories": [
+    '../../../packages/(semi-animation-react|semi-animation-styled)/_story/*.react.stories.(js|jsx)',
+  ],
+  typescript: {
+    check: false,
+    checkOptions: {}
+  },
+};

+ 78 - 0
.storybook/base/base.js

@@ -0,0 +1,78 @@
+
+const path = require('path');
+const _ = require('lodash');
+
+function resolve(...dirs) {
+    return path.join(__dirname, '../..', ...dirs);
+}
+
+module.exports = {
+  "addons": [
+    {
+      name: "storybook-addon-turbo-build",
+      options: {
+        optimizationLevel: 3,
+      },
+    },
+  ],
+  webpackFinal: async (config) => {
+    const rules =
+        (config.module.rules &&
+            config.module.rules.filter(rule => {
+                const test = _.toString(rule && rule.test);
+                if (/\.css/i.test(test) || /\.s(c|a)ss/i.test(test)) {
+                    return false;
+                }
+                return true;
+            })) ||
+        [];
+    rules.unshift({
+        test: /\.tsx/,
+        exclude: /node_modules/,
+        loader: 'esbuild-loader',
+        options: {
+            loader: 'tsx',
+            target: 'es2015'
+        }
+    });
+    rules.unshift({
+        test: /\.ts/,
+        exclude: /node_modules/,
+        loader: 'esbuild-loader',
+        options: {
+            loader: 'ts',
+            target: 'es2015'
+        }
+    });
+    rules.push(
+        {
+            test: /\.css$/,
+            use: ['style-loader', 'css-loader']
+        },
+    );
+    rules.push(
+        {
+            test: /\.s(a|c)ss$/,
+            include: [resolve('packages/semi-ui'), resolve('packages/semi-foundation'), resolve('packages/semi-icons')],
+            use: ['style-loader', 'css-loader', 'sass-loader', resolve('packages/semi-webpack/lib/semi-theme-loader.js')],
+        }
+    );
+    config.module.rules = rules;
+    config.resolve.extensions.push('.js', '.jsx', '.ts', '.tsx');
+    config.resolve.symlinks = false;
+    config.resolve.alias = {
+        '@douyinfe/semi-foundation': resolve('packages/semi-foundation'),
+        '@douyinfe/semi-icons': resolve('packages/semi-icons/src'),
+        '@douyinfe/semi-ui': resolve('packages/semi-ui'),
+        '@douyinfe/semi-theme-default': resolve('packages/semi-theme-default'),
+        '@douyinfe/semi-illustrations': resolve('packages/semi-illustrations/src'),
+        '@douyinfe/semi-animation': resolve('packages/semi-animation'),
+        '@douyinfe/semi-animation-react': resolve('packages/semi-animation-react'),
+        '@douyinfe/semi-animation-styled': resolve('packages/semi-animation-styled')
+    };
+    config.devtool = 'source-map';
+    
+    return config;
+  }
+};
+

+ 12 - 0
.storybook/js/main.js

@@ -0,0 +1,12 @@
+const config = require('../base/base');
+
+module.exports = {
+  ...config,
+  "stories": [
+    '../../packages/semi-ui/**/_story/*.stories.(js|jsx)',
+  ],
+  typescript: {
+    check: false,
+    checkOptions: {}
+  },
+};

+ 2 - 0
.storybook/preview.js

@@ -0,0 +1,2 @@
+import 'reset-css';
+import 'normalize.css';

+ 9 - 0
.storybook/ts/main.js

@@ -0,0 +1,9 @@
+const config = require('../base/base');
+
+module.exports = {
+  ...config,
+  "stories": [
+    '../../packages/semi-ui/**/_story/*.stories.(ts|tsx)',
+  ],
+};
+

+ 71 - 0
.storybook/v5config/base/config.js

@@ -0,0 +1,71 @@
+import { configure, addDecorator, addParameters } from '@storybook/react';
+import 'reset-css';
+import 'normalize.css';
+
+const config = loadStories => {
+    // Option defaults:
+    addParameters({
+        options: {
+            /**
+             * show story component as full screen
+             * @type {Boolean}
+             */
+            isFullscreen: false,
+            /**
+             * display panel that shows a list of stories
+             * @type {Boolean}
+             */
+            showNav: true,
+            /**
+             * display panel that shows addon configurations
+             * @type {Boolean}
+             */
+            showPanel: true,
+            /**
+             * where to show the addon panel
+             * @type {('bottom'|'right')}
+             */
+            panelPosition: 'bottom',
+            /**
+             * regex for finding the hierarchy separator
+             * @example:
+             *   null - turn off hierarchy
+             *   /\// - split by `/`
+             *   /\./ - split by `.`
+             *   /\/|\./ - split by `/` or `.`
+             * @type {Regex}
+             */
+            hierarchySeparator: /\/|\./,
+            /**
+             * regex for finding the hierarchy root separator
+             * @example:
+             *   null - turn off multiple hierarchy roots
+             *   /\|/ - split by `|`
+             * @type {Regex}
+             */
+            hierarchyRootSeparator: /\|/,
+            /**
+             * sidebar tree animations
+             * @type {Boolean}
+             */
+            sidebarAnimations: true,
+            /**
+             * enable/disable shortcuts
+             * @type {Boolean}
+             */
+            enableShortcuts: true,
+            /**
+             * show/hide tool bar
+             * @type {Boolean}
+             */
+            isToolshown: true,
+            /**
+             * theme storybook, see link below
+             */
+            theme: undefined,
+        },
+    });
+    configure(loadStories, module);
+};
+
+export default config;

+ 82 - 0
.storybook/v5config/base/webpack.config.js

@@ -0,0 +1,82 @@
+// you can use this file to add your custom webpack plugins, loaders and anything you like.
+// This is just the basic way to add additional webpack configurations.
+// For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config
+
+// IMPORTANT
+// When you add this file, we won't add the default configurations which is similar
+// to "React Create App". This only has babel loader to load JavaScript.
+const path = require('path');
+const _ = require('lodash');
+const SemiWebpackPlugin = require('../../packages/semi-ui-plugin-core');
+
+function resolve(...dirs) {
+    return path.join(__dirname, '../..', ...dirs);
+}
+
+module.exports = ({ config }) => {
+    const rules =
+        (config.module.rules &&
+            config.module.rules.filter(rule => {
+                const test = _.toString(rule && rule.test);
+                if (/\.css/i.test(test) || /\.s(c|a)ss/i.test(test)) {
+                    return false;
+                }
+                return true;
+            })) ||
+        [];
+    rules.push(
+        {
+            test: /\.css$/,
+            loaders: ['style-loader', 'css-loader'],
+        },
+        {
+            test: /\.tsx?$/,
+            use: [
+                {
+                    loader: require.resolve('awesome-typescript-loader'),
+                },
+            ],
+        },
+        {
+            test: /\.svg?$/,
+            use: ['@svgr/webpack']
+        }
+    );
+    config.module.rules = rules;
+    config.resolve.extensions.push('.js', '.jsx', '.ts', '.tsx');
+    config.resolve.symlinks = false;
+    config.resolve.alias = {
+        '@douyinfe/semi-foundation': resolve('packages/semi-foundation'),
+        '@douyinfe/semi-ui': resolve('packages/semi-ui'),
+        '@douyinfe/semi-icons': resolve('packages/semi-icons/src'),
+        '@douyinfe/semi-theme-default': resolve('packages/semi-theme-default'),
+        '@douyinfe/semi-illustrations': resolve('packages/semi-illustrations/src'),
+    };
+    config.devtool = 'source-map';
+    // config.devtool = 'cheap-source-map';
+    config.plugins.push(
+        new SemiWebpackPlugin({
+            theme: '@douyinfe/semi-theme-default',
+            esbuild: true,
+            paths: [
+                function check(path) {
+                    return (
+                        (/packages\/semi-foundation/i.test(path) ||
+                            /packages\/semi-ui/i.test(path) ||
+                            /packages\/semi-icons/i.test(path)) &&
+                        !(
+                            /packages\/semi-foundation\/node_modules/i.test(path) ||
+                            /packages\/semi-ui\/node_modules/i.test(path)
+                        )
+                    );
+                },
+            ],
+            scssPaths: [
+                resolve('packages/semi-foundation'),
+                resolve('packages/semi-ui'),
+                resolve('packages/semi-theme-default'),
+            ],
+        })
+    );
+    return config;
+};

+ 1 - 0
.storybook/v5config/js/addons.js

@@ -0,0 +1 @@
+import '../base/addons';

+ 8 - 0
.storybook/v5config/js/config.js

@@ -0,0 +1,8 @@
+import config from '../base/config';
+
+// automatically import all files ending in *.stories.js
+const req = require.context('../../packages/semi-ui', true, /.stories.js$/);
+function loadStories() {
+    req.keys().forEach(filename => req(filename));
+}
+config(loadStories);

+ 8 - 0
.storybook/v5config/js/webpack.config.js

@@ -0,0 +1,8 @@
+// you can use this file to add your custom webpack plugins, loaders and anything you like.
+// This is just the basic way to add additional webpack configurations.
+// For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config
+
+// IMPORTANT
+// When you add this file, we won't add the default configurations which is similar
+// to "React Create App". This only has babel loader to load JavaScript.
+module.exports = require('../base/webpack.config');

+ 1 - 0
.storybook/v5config/ts/addons.js

@@ -0,0 +1 @@
+import '../base/addons';

+ 8 - 0
.storybook/v5config/ts/config.js

@@ -0,0 +1,8 @@
+import config from '../base/config';
+
+// automatically import all files ending in *.stories.tsx
+const req = require.context('../../packages/semi-ui', true, /.stories.tsx$/);
+function loadStories() {
+    req.keys().forEach(filename => req(filename));
+}
+config(loadStories);

+ 8 - 0
.storybook/v5config/ts/webpack.config.js

@@ -0,0 +1,8 @@
+// you can use this file to add your custom webpack plugins, loaders and anything you like.
+// This is just the basic way to add additional webpack configurations.
+// For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config
+
+// IMPORTANT
+// When you add this file, we won't add the default configurations which is similar
+// to "React Create App". This only has babel loader to load JavaScript.
+module.exports = require('../base/webpack.config');

+ 42 - 0
.stylelintrc.js

@@ -0,0 +1,42 @@
+module.exports = {
+    rules: {
+        'indentation': [4, { severity: 'error' }],
+        'no-missing-end-of-source-newline': [true, { severity: 'warning' }],
+        'block-opening-brace-space-before': ['always', { severity: 'warning' }],
+        'declaration-colon-space-after': ['always', { severity: 'warning' }],
+        'declaration-colon-space-before': ['never', { severity: 'warning' }],
+        'max-line-length': [120, { severity: 'warning' }],
+        'selector-list-comma-newline-after': ['always', { severity: 'warning' }],
+        'selector-combinator-space-before': ['always', { severity: 'warning' }],
+        'selector-combinator-space-after': ['always', { severity: 'warning' }],
+        'selector-attribute-quotes': ['always', { severity: 'warning' }],
+        'block-opening-brace-newline-after': ['always', { severity: 'warning' }],
+        'selector-no-qualifying-type': [true, { severity: 'warning' }],
+        'shorthand-property-no-redundant-values': [true, { severity: 'warning' }],
+        'declaration-no-important': [true, { severity: 'warning' }],
+        'string-quotes': ['double', { severity: 'warning' }],
+        'number-leading-zero': ['never', { severity: 'warning' }],
+        'function-url-quotes': ['never', { severity: 'warning' }],
+        'length-zero-no-unit': [true, { severity: 'warning' }],
+        'color-hex-length': ['short', { severity: 'warning' }],
+        'color-hex-case': ['lower', { severity: 'warning' }],
+        'color-named': ['never', { severity: 'warning' }],
+        'font-weight-notation': ['numeric', { severity: 'warning' }],
+        'font-family-name-quotes': ['always-unless-keyword', { severity: 'warning' }],
+        'media-feature-range-operator-space-before': ['always', { severity: 'warning' }],
+        'media-feature-range-operator-space-after': ['always', { severity: 'warning' }],
+        'media-feature-colon-space-before': ['never', { severity: 'warning' }],
+        'media-feature-colon-space-after': ['always', { severity: 'warning' }],
+        'no-duplicate-selectors': [true, { severity: 'warning' }],
+        'rule-empty-line-before': ['always', { severity: 'warning' }],
+        'selector-attribute-operator-space-before': ['never', { severity: 'warning' }],
+        'selector-attribute-operator-space-after': ['never', { severity: 'warning' }],
+        'declaration-block-trailing-semicolon': ['always', { severity: 'warning' }],
+        'selector-attribute-brackets-space-inside': ['never', { severity: 'warning' }],
+        'comment-whitespace-inside': ['always', { severity: 'warning' }],
+        'comment-empty-line-before': ['always', { severity: 'warning' }],
+        'selector-pseudo-class-parentheses-space-inside': ['never', { severity: 'warning' }],
+        'media-feature-parentheses-space-inside': ['never', { severity: 'warning' }],
+        'function-calc-no-unspaced-operator': [true, { severity: 'warning' }],
+    },
+};

+ 74 - 0
.vscode/launch.json

@@ -0,0 +1,74 @@
+{
+    // 使用 IntelliSense 了解相关属性。
+    // 悬停以查看现有属性的描述。
+    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Debug UnitTest",
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/.bin/jest",
+                "${workspaceRoot}/packages/semi-ui/form/", // 需要调试哪个组件,替换文件夹路径即可
+                "--runInBand",
+                "--coverage",
+                "--silent" // ignore warning such as componentWillReceiveProps will be abondon...
+            ],
+            "env": {
+                "NODE_ENV": "test",
+                // "type": "story" // 调试snapshot快照的时候用这个
+                "type": "unit"     // 调试unitTest的时候用这个
+            },
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen",
+            "port": 9229
+        },
+        {
+            "type": "node",
+            "request": "launch",
+            "name": "compile css",
+            "env": {
+                "NODE_ENV": "dev"
+            },
+            "runtimeExecutable": "node",
+            "program": "${workspaceFolder}/scripts/build-css.js",
+            "restart": true,
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen"
+        },
+        {
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+            ],
+            "name": "debug snapshot update",
+            "env": {
+                "NODE_ENV": "dev"
+            },
+            "runtimeExecutable": "node",
+            "program": "${workspaceFolder}/scripts/snapshotUpdate.js",
+            "restart": true,
+            "console": "integratedTerminal",
+        },
+        {
+            "name": "Debug StorySnapShot",
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/.bin/jest",
+                "--runInBand",
+                "--silent" // ignore warning such as componentWillReceiveProps will be abondon...
+            ],
+            "env": {
+                "NODE_ENV": "test",
+                "type": "story"
+            },
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen",
+            "port": 9229
+        }
+    ]
+}

+ 49 - 0
.vscode/settings.json

@@ -0,0 +1,49 @@
+{
+    "[typescript]": {
+        "editor.formatOnSave": false,
+        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+    },
+    "[javascript]": {
+        "editor.formatOnSave": false,
+        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+    },
+    "[scss]": {
+        "editor.formatOnPaste": false
+    },
+    "[javascriptreact]": {
+        "editor.defaultFormatter": "carlsirce.vscode-eden-plugin",
+        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+    },
+    "[less]": {
+        "editor.defaultFormatter": "michelemelluso.code-beautifier"
+    },
+    "[typescriptreact]": {
+        "editor.defaultFormatter": "carlsirce.vscode-eden-plugin",
+        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+    },
+    "typescript.updateImportsOnFileMove.enabled": "always",
+    "files.autoSave": "off",
+    "[json]": {
+        "editor.defaultFormatter": "vscode.json-language-features"
+    },
+    "[css]": {
+        "editor.defaultFormatter": "michelemelluso.code-beautifier"
+    },
+    "editor.tabSize": 4,
+    "eden-develop-environment.loose": true,
+    "eden-develop-environment.temporaryHideWarnings": true,
+    "git.ignoreLimitWarning": true,
+    "edenDevelopEnvironment.loose": true,
+    "edenDevelopEnvironment.temporaryHideWarnings": true,
+    "i18n-ally.localesPaths": [
+        "src/locale",
+        "packages/semi-ui-react/locale",
+        "content/other/locale",
+        "public/page-data/en-US/other/locale",
+        "public/page-data/zh-CN/other/locale"
+    ],
+    "cSpell.words": [
+        "backtop",
+        "Splited"
+    ]
+}

+ 43 - 0
CONTRIBUTING-en-US.md

@@ -0,0 +1,43 @@
+# Contributing
+
+We are glad that you are interested in contributing to Semi UI. Please take some minutes to read the following guidelines:
+## Branch Management
+ - main: Normally, the branch is just a snapshot of the latest stable release. We will merge the `beta` to this branch releasing a minor version every two weeks. If an emergency bug is fixed, we will release a patch version on this branch.
+ - beta: For bug fixes and feature development. The beta version will be released based on this branch one week after the minor version is released
+## Bug
+We use Github issues to track bugs. In order to understand and fix bugs faster, when reporting a bug, you can also reproduce the problem through the template we provide. we recommend you
+## Feature
+If you have an idea to provide or optimize features, we recommend that you use Github issues to suggest a new issue
+## Pull Request Guidelines
+The Semi Design team will take every Pull Request seriously. We will review and merge your code. It is also possible to suggest some modifications to your code.
+To open a Pull Request, please follow the steps below:
+ - Fork our repo, then clone your fork
+```bash
+git clone https://github.com/<your-username>/semi-ui.git
+cd semi-ui
+```
+ - Checkout to `beta` branch, install the dependencies
+```bash
+git checkout beta
+npm run bootstrap
+```
+ - Next, make the modifications you want to make, which can be bug fixes or development of new features
+ - You can verify your change by running storybook (`npm start`) and official website (`npm run docstie`) locally
+ - Add accompanying tests for your change, ensure all tests pass
+```bash
+npm run test:unit
+```
+ - Open a Pull Request against `beta` of source repo
+
+## Help Improve the Docs
+The documentation site is based on [gatsby](https://www.gatsbyjs.com/), and the code is in the `src` directory.
+
+**The component documentation is located in the md file under the `semi-ui` component folder. ** Take tooltip as an example:
+
+* Chinese document `packages/semi-ui/tooltip/index.md` 
+* English document `packages/semi-ui/tooltip/index-en-US.md`
+To get started:
+```sh
+npm run docsite
+```
+If you are interested in helping us improve the doc, please modify the md file of the component and submit your changes according to the Pull Request guidelines

+ 46 - 0
CONTRIBUTING.md

@@ -0,0 +1,46 @@
+# 贡献指南
+
+我们很高兴您有兴趣为 Semi UI 做出贡献。 在提交您的贡献之前,请务必花点时间阅读以下指南:
+
+## 分支管理
+ - main: 通常情况下该分支仅作为最新稳定版本代码的快照,用于发布正式版本。每双周会合并`beta`到此分支发布一个minor版本。如果修复了紧急bug,我们会基于此分支修复并发布patch版本
+ - beta: 用于bug修复和feature开发。发布minor版本后的一周会基于此分支发布beta版本
+## Bug
+我们使用 Github issues 来追踪 bug。为了更快地了解和解决bug,在提交issue时,你也可以通过我们提供的模板来重现问题。
+## 新特性
+如果你有提供或者优化功能的想法,我们推荐你使用Github issues来新建一个添加新功能的issue。
+
+## Pull Request指南
+Semi Design团队会认真对待每一个Pull Request。我们会review并合并你的代码。也有可能对你的代码提出一些修改意见。
+
+要提交一个Pull Request,请遵循以下步骤:
+ - Fork 项目并克隆下来
+```bash
+git clone https://github.com/<your-username>/semi-ui.git
+cd semi-ui
+```
+ - 切换到`beta`分支,完成项目依赖安装
+```bash
+git checkout beta
+npm run bootstrap
+```
+ - 接下来进行你想要做的修改,可以是bug修复,也可以是新功能的开发
+ - 你可以通过运行storybook(`npm start`)和官网(`npm run docstie`)来验证逻辑
+ - 为你的修改编写测试用例,并确保测试通过
+```bash
+npm run test:unit
+```
+ - 新建一个Pull Request到源项目的`beta`分支
+
+## 帮助改善文档
+文档站基于 [gatsby](https://www.gatsbyjs.com/) 构建,核心代码在 `src` 目录。
+
+**组件文档位于 `semi-ui` 组件文件夹下的 md 文件。** 以 tooltip 为例:
+
+* 中文文档 `packages/semi-ui/tooltip/index.md` 
+* 英文文档 `packages/semi-ui/tooltip/index-en-US.md`
+启动文档站点
+```sh
+npm run docsite
+```
+如果您有兴趣帮助我们提高文档的质量,请修改对应组件的md文件,按照Pull Request指南提交您的改动

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 DouyinFE
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 99 - 0
README-zh-CN.md

@@ -0,0 +1,99 @@
+<article style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
+    <p><img width="200" height="100%" src="https://lf1-cdn-tos.bytescm.com/obj/ttfe/ies/semi/SemiLogo/Logo_1576122865926.png" /></p>
+    <h1 style="width: 100%; text-align: center;">Semi-UI</h1>
+    <p>
+        现代、全面、灵活的设计系统和 UI 库。 快速搭建美观的React 应用。
+    </p>
+    <p style="display: flex">
+        <img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/Semi_info.gif" />
+    </p>
+</article>
+
+简体中文 | [English](./README.md)
+
+# 🎉 特性
+
+- 💪 58+高质量组件
+- 💅 强大的定制定力,上千个Design Token
+- 🌍 国际化支持14种语言
+- 👏 使用TypeScript,良好的类型定义
+- 🥳 支持SSR
+- 🤩
+
+# 🔥 安装
+
+```sh
+# 使用 npm
+npm install @douyinfe/semi-ui
+
+# 使用 yarn
+yarn add @douyinfe/semi-ui
+
+```
+
+# 👍 使用
+
+这是一个快速开始的例子:
+
+```jsx
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { Button, Switch } from '@douyinfe/semi-ui';
+
+const App = () => (
+  <>
+    <Button type="primary">primary button</Button>
+    <Switch size='large' />
+  </>
+);
+
+ReactDOM.render(<App />, document.querySelector('#app'));
+```
+
+[Semi UI官网](https://semi.design) 拥有上千个支持实时调试的例子,欢迎体验使用。
+
+# 📌 文档
+
+* [快速开始](https://semi.design/zh-CN/start/getting-started)
+* [组件总览](https://semi.design/zh-CN/start/overview)
+* [自定义主题](https://semi.design/zh-CN/start/customize-theme)
+* [Design Tokens](https://semi.design/zh-CN/basic/tokens)
+* [暗色模式](https://semi.design/zh-CN/start/dark-mode)
+* [Icons](https://semi.design/zh-CN/basic/icon)
+* [全局配置](https://semi.design/zh-CN/other/configprovider)
+* [国际化](https://semi.design/zh-CN/other/locale)
+* [常见问题](https://semi.design/zh-CN/start/faq)
+* [CHANGELOG](https://semi.design/zh-CN/start/changelog)
+
+# 👌 平台支持
+
+Semi UI 支持所有主流浏览器。
+
+|[<img alt="chrome" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/chrome/chrome.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/chrome/chrome.png)<br>chrome|[<img alt="firefox" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/firefox/firefox.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/firefox/firefox.png)<br>firefox|[<img alt="safari" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/safari/safari.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/safari/safari.png)<br>safari|[<img alt="IE/Edge" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/edge/edge.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/edge/edge.png)<br> IE/Edge|[<img alt="electron" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/electron/electron.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/electron/electron.png)<br>Electron|
+|--|--|--|--|--|
+| latest 2 versions | latest 2 versions | latest 2 version | Edge | latest 2 version |
+
+# 👐 贡献指南
+
+阅读贡献指南了解我们的开发流程,包括开发规范、测试规范和构建规范等。
+
+[CONTRIBUTING](CONTRIBUTING.md)
+
+
+# 交流群
+
+有任何问题可以进群交流,我们会及时给予解答和反馈。
+
+<div>
+  <div>飞书群:</div>
+  <img width="200px" src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/lark_qrcode.png" />
+</div>
+
+<div>
+  <div>微信群:</div>
+  <img width="200px" src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/wechat_qrcode.png" />
+</div>
+
+# 🎈 协议
+
+Semi UI 使用 [MIT 协议](LICENSE)

+ 84 - 0
README.md

@@ -0,0 +1,84 @@
+<article style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
+    <p><img width="200" height="100%" src="https://lf1-cdn-tos.bytescm.com/obj/ttfe/ies/semi/SemiLogo/Logo_1576122865926.png" /></p>
+    <h1 style="width: 100%; text-align: center;">Semi-UI</h1>
+    <p>
+        A modern, comprehensive, flexible design system and UI library. Quickly build beautiful React apps.
+    </p>
+    <p style="display: flex">
+        <img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/Semi_info.gif" />
+    </p>
+</article>
+
+English | [简体中文](./README-zh_CN.md)
+
+# 🎉 Features
+
+- 💪 Up to 58 high-quality Components.
+- 💅 Thousands Design Tokens. Powerful Themes Customizing.
+- 🌍 Internationalization Support for Dozens of Languages.
+- 👏 Written in Typescript, Friendly Static Type Support.
+- 🥳 SSR (Sever Side Rendering) Compatible.
+- 🤩
+
+# 🔥 Install
+
+```sh
+# with npm
+npm install @douyinfe/semi-ui
+
+# with yarn
+yarn add @douyinfe/semi-ui
+
+```
+
+# 👍 Usage
+
+Here is a quick example to get you started, it's all you need:
+
+```jsx
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { Button, Switch } from '@douyinfe/semi-ui';
+
+const App = () => (
+  <>
+    <Button type="primary">primary button</Button>
+    <Switch size='large' />
+  </>
+);
+
+ReactDOM.render(<App />, document.querySelector('#app'));
+```
+
+And [Semi UI Doc Site]() have hundreds editable examples and live preview, welcome play with those examples.
+
+# 📌 Documentation
+
+* [Quick Start](https://semi.design/zh-CN/start/getting-started)
+* [Components Overview](https://semi.design/zh-CN/start/overview)
+* [Customizing Themes](https://semi.design/zh-CN/start/customize-theme)
+* [Design Tokens](https://semi.design/zh-CN/basic/tokens)
+* [Dark Mode](https://semi.design/zh-CN/start/dark-mode)
+* [Semi Icons](https://semi.design/zh-CN/basic/icon)
+* [Global Config](https://semi.design/zh-CN/other/configprovider)
+* [Internationalization](https://semi.design/zh-CN/other/locale)
+* [FAQ](https://semi.design/zh-CN/start/faq)
+* [CHANGELOG](https://semi.design/zh-CN/start/changelog)
+
+# 👌 Platform Support
+
+Semi UI supports all major modern browsers.
+
+|[<img alt="chrome" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/chrome/chrome.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/chrome/chrome.png)<br>chrome|[<img alt="firefox" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/firefox/firefox.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/firefox/firefox.png)<br>firefox|[<img alt="safari" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/safari/safari.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/safari/safari.png)<br>safari|[<img alt="IE/Edge" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/edge/edge.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/edge/edge.png)<br> IE/Edge|[<img alt="electron" height="24px" src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/electron/electron.png" />](https://cdnjs.cloudflare.com/ajax/libs/browser-logos/70.4.0/electron/electron.png)<br>Electron|
+|--|--|--|--|--|
+| latest 2 versions | latest 2 versions | latest 2 version | Edge | latest 2 version |
+
+# 👐 Contributing
+
+Read the contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Semi UI.
+
+See [CONTRIBUTING](CONTRIBUTING.md) documentation.
+
+# 🎈 License
+
+Semi UI is [MIT Licensed](LICENSE)

+ 27 - 0
babel.config.js

@@ -0,0 +1,27 @@
+const env = process.env.BABEL_ENV || process.env.NODE_ENV;
+
+module.exports = {
+    presets: [
+        [
+            '@babel/preset-env',
+            {
+                modules: env === 'test' ? 'cjs' : false,
+                debug: false,
+            },
+        ],
+        '@babel/preset-react',
+        '@babel/preset-typescript'
+    ],
+    plugins: [
+        '@babel/plugin-transform-runtime',
+        [
+            '@babel/plugin-proposal-decorators',
+            {
+                legacy: true,
+            },
+        ],
+        '@babel/plugin-proposal-class-properties',
+        '@babel/plugin-proposal-object-rest-spread',
+        env === 'test' && 'babel-plugin-transform-require-context',
+    ].filter(Boolean)
+};

+ 338 - 0
content/basic/grid/index-en-US.md

@@ -0,0 +1,338 @@
+---
+localeCode: en-US
+order: 9
+category: Basic
+title:  Grid
+icon: doc-grid
+dir: column
+brief: 24 grid system.
+---
+
+
+## Overview
+
+The grid system of layout, we define the external framework of information blocks based on row and column (col) to ensure that each area of the page can be robustly arranged.
+
+## Flex layout
+
+Our grid system supports the Flex layout, allowing the horizontal alignment of child elements within the parent node - left, center, right, equal width, scattered arrangement. Between child elements and child elements, support top alignment, vertical center alignment, bottom alignment. At the same time, support the use of `order` To define the order of the elements.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Col, Row } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+From stacking to horizontal arrangement.
+
+Using a single set of Row and Col grid components, you can create a basic grid system. All Col must be placed in the Row.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+      <Row>
+          <Col span={24}><div className="col-content">col-24</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={12}><div className="col-content">col-12</div></Col>
+          <Col span={12}><div className="col-content">col-12</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+      </Row>
+  </div>
+) 
+```
+
+### Gutter interval
+
+The grid often needs to work with the interval. You can use Row's `Gutter` Properties, we recommend using (16 + 8n) px as a grid interval. (n is a natural number)
+
+Vertical gutter can be in the form of an array. The first item of the array is horizontal gutter and the second item is vertical gutter.<br/>
+
+If you want to support responsiveness, you can write {xs: 8, sm: 16, md: 24, lg: 32}.<br/>
+
+**Vertical gutter in array form supported from version `1.11.0`**<br/>
+
+Dark for content area, light for spacing
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid grid-gutter">
+    <p>horizontal</p>
+    <hr />
+    <Row gutter={16}>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+    <p>vertical</p>
+    <hr />
+    <Row gutter={[16, 24]}>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+  </div>
+)
+```
+
+### Offset
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <Row>
+      <Col span={8}><div className="col-content">col-8</div></Col>
+      <Col span={8} offset={8}>
+        <div className="col-content">col-8</div>
+      </Col>
+    </Row>
+    <br/>
+    <Row>
+      <Col span={6} offset={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6} offset={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+    <br/>
+    <Row>
+      <Col span={12} offset={6}>
+        <div className="col-content">col-12</div>
+      </Col>
+    </Row>
+  </div>
+)
+```
+
+### Use Flex layout
+
+Use `row-flex` to define a Flex layout whose child elements are based on different values `start`,`center`,`end`,`space-between`,`space-around`, define their typesetting methods in the parent node respectively.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <p>sub-element align left</p>
+    <Row type="flex" justify="start">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align center</p>
+    <Row type="flex" justify="center">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align right</p>
+    <Row type="flex" justify="end">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element monospaced arrangement</p>
+    <Row type="flex" justify="space-between">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align full</p>
+    <Row type="flex" justify="space-around">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+  </div>
+)
+```
+
+### Flex subelements vertically aligned
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid grid-flex">
+      <p>Align Top</p>
+      <Row type="flex" justify="center" align="top">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+
+      <p>Align Center</p>
+      <Row type="flex" justify="space-around" align="middle">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+
+      <p>Align Bottom</p>
+      <Row type="flex" justify="space-between" align="bottom">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+  </div>
+)
+```
+
+### Flex element sorting
+
+Change the sorting of elements through `order` of the Col.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <Row type="flex">
+      <Col span={6} order={4}><div className="col-content">col-4</div></Col>
+      <Col span={6} order={3}><div className="col-content">col-3</div></Col>
+      <Col span={6} order={2}><div className="col-content">col-2</div></Col>
+      <Col span={6} order={1}><div className="col-content">col-1</div></Col>
+    </Row>
+  </div>
+)
+```
+
+### Responsive
+
+Referring to Bootstrap's responsive design, preset six response sizes:`xs`, `sm`, `md`, `lg`, `Xl`, `xxl`.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+ <div className="grid">
+    <Row gutter={{xs:16,sm:16,md:16,lg:24,xl:24,xxl:24}}>
+        <Col xs={2} sm={4} md={6} lg={8} xl={10}><div className="col-content">Col</div></Col>
+        <Col xs={20} sm={16} md={12} lg={8} xl={4}><div className="col-content">Col</div></Col>
+        <Col xs={2} sm={4} md={6} lg={8} xl={10}><div className="col-content">Col</div></Col>
+    </Row>
+    <br/>
+    <Row>
+        <Col xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+        <Col xs={{ span: 11, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+        <Col xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+    </Row>
+  </div>
+)
+```
+
+## API reference
+
+### Row
+
+| Properties | Instructions  | type | Default |
+| ----- | ---- | ---- | ---- |
+| align  | Vertical alignment under flex layout: `top` `middle` `bottom` | string  | |
+| className | Class name | string| |
+| gutter | Grid interval, can be written as pixel value or support responsive object writing `{ xs: 8, sm: 16, md: 24}`, Vertical gutter support from version **1.11.0** | number / object / array |  |
+| justify  | Horizontal arrangement under flex layout: `start` `end` `center` `space-around` `space-between` | string  | `start` |
+| style | style | CSSProperties | |
+| type  | Layout mode, optional `flex`, valid under [Modern Browser](http://caniuse.com/#search=flex)  | string  |  |
+
+### Col
+
+| Properties | Instructions                                                                                        | type           | Default |
+| ---------- | --------------------------------------------------------------------------------------------------- | -------------- | ------- |
+| lg         | `≥ 992px` responsive grid, which can be a number of grids or an object containing other properties  | number\|object | -       |
+| md         | `≥ 768px` responsive grid, which can be a number of grids or an object containing other properties  | number\|object | -       |
+| offset     | The number of interval cells on the left side of a grid. There can be no grid in the interval.      | number         | 0       |
+| order      | Grid order, effective in `flex` layout mode                                                         | number         | 0       |
+| pull       | The grid moves to the left.                                                                         | number         | 0       |
+| push       | The grid moves to the right.                                                                        | number         | 0       |
+| sm         | `≥ 576px` responsive grid, which can be a number of grids or an object containing other properties  | number\|object | -       |
+| span       | The number of grid spaces is equivalent to `display: none` when it is 0                             | number         | -       |
+| xl         | `≥ 1200px` responsive grid, which can be a number of grids or an object containing other properties | number\|object | -       |
+| xs         | `< 576px` responsive grid, which can be a number of grids or an object containing other attributes  | number\|object | -       |
+| xxl        | `≥ 1600px` responsive grid, which can be a number of grids or an object containing other properties | number\|object | -       |
+
+## Design Tokens
+<DesignToken/>

+ 338 - 0
content/basic/grid/index.md

@@ -0,0 +1,338 @@
+---
+localeCode: zh-CN
+order: 9
+category: 基础
+title:  Grid 布局
+icon: doc-grid
+dir: column
+brief: 24 栅格系统。
+---
+
+## 概述
+
+布局的栅格化系统,我们是基于行(row)和列(col)来定义信息区块的外部框架,以保证页面的每个区域能够稳健地排布起来。
+
+## 弹性布局
+
+我们的栅格化系统支持 Flex 布局,允许子元素在父节点内的水平对齐方式 - 居左、居中、居右、等宽排列、分散排列。子元素与子元素之间,支持顶部对齐、垂直居中对齐、底部对齐的方式。同时,支持使用 `order` 来定义元素的排列顺序。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Col, Row } from '@douyinfe/semi-ui';
+```
+
+### 基础使用
+
+从堆叠到水平排列。
+
+使用单一的一组 Row 和 Col 栅格组件,就可以创建一个基本的栅格系统,所有 Col 必须放在 Row 内。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+      <Row>
+          <Col span={24}><div className="col-content">col-24</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={12}><div className="col-content">col-12</div></Col>
+          <Col span={12}><div className="col-content">col-12</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+          <Col span={8}><div className="col-content">col-8</div></Col>
+      </Row>
+      <br/>
+      <Row>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+          <Col span={6}><div className="col-content">col-6</div></Col>
+      </Row>
+  </div>
+)
+```
+
+### Gutter 间隔
+
+栅格常常需要和间隔进行配合,你可以使用 Row 的 `gutter` 属性,我们推荐使用 (16+8n)px 作为栅格间隔。(n 是自然数)
+
+垂直间隔可以使用数组形式,数组第一项为横向间隔,第二项为垂直间隔。  
+
+如果要支持响应式,可以写成 `{ xs: 8, sm: 16, md: 24, lg: 32 }`  
+
+**从`1.11.0`版本起支持数组形式的垂直间隔**
+
+深色为内容物区域,浅色为间隔
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid grid-gutter">
+    <p>horizontal</p>
+    <hr />
+    <Row gutter={16}>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+    <p>vertical</p>
+    <hr />
+    <Row gutter={[16, 24]}>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+  </div>
+)
+```
+
+### Offset 偏移
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <Row>
+      <Col span={8}><div className="col-content">col-8</div></Col>
+      <Col span={8} offset={8}>
+        <div className="col-content">col-8</div>
+      </Col>
+    </Row>
+    <br/>
+    <Row>
+      <Col span={6} offset={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+      <Col span={6} offset={6}>
+        <div className="col-content">col-6</div>
+      </Col>
+    </Row>
+    <br/>
+    <Row>
+      <Col span={12} offset={6}>
+        <div className="col-content">col-12</div>
+      </Col>
+    </Row>
+  </div>
+)
+```
+
+### Flex 布局
+
+使用 `row-flex` 定义 Flex 布局,其子元素根据不同的值 `start`,`center`,`end`,`space-between`,`space-around`,分别定义其在父节点里面的排版方式。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <p>sub-element align left</p>
+    <Row type="flex" justify="start">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align center</p>
+    <Row type="flex" justify="center">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align right</p>
+    <Row type="flex" justify="end">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element monospaced arrangement</p>
+    <Row type="flex" justify="space-between">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+
+    <p>sub-element align full</p>
+    <Row type="flex" justify="space-around">
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+        <Col span={4}><div className="col-content">col-4</div></Col>
+    </Row>
+  </div>
+)
+```
+
+### Flex 子元素垂直对齐
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid grid-flex">
+      <p>Align Top</p>
+      <Row type="flex" justify="center" align="top">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+
+      <p>Align Center</p>
+      <Row type="flex" justify="space-around" align="middle">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+
+      <p>Align Bottom</p>
+      <Row type="flex" justify="space-between" align="bottom">
+          <Col span={4}><div className="col-content" value={100}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={50}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={120}>col-4</div></Col>
+          <Col span={4}><div className="col-content" value={80}>col-4</div></Col>
+      </Row>
+  </div>
+)
+```
+
+### Flex 元素排序
+
+通过 Flex 布局的 Order 来改变元素的排序。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+  <div className="grid">
+    <Row type="flex">
+      <Col span={6} order={4}><div className="col-content">col-4</div></Col>
+      <Col span={6} order={3}><div className="col-content">col-3</div></Col>
+      <Col span={6} order={2}><div className="col-content">col-2</div></Col>
+      <Col span={6} order={1}><div className="col-content">col-1</div></Col>
+    </Row>
+  </div>
+)
+```
+
+### 响应式
+
+参照 Bootstrap 的 响应式设计,预设六个响应尺寸:`xs`, `sm`, `md`, `lg`, `xl`, `xxl`。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+ <div className="grid">
+    <Row gutter={{xs:16,sm:16,md:16,lg:24,xl:24,xxl:24}}>
+        <Col xs={2} sm={4} md={6} lg={8} xl={10}><div className="col-content">Col</div></Col>
+        <Col xs={20} sm={16} md={12} lg={8} xl={4}><div className="col-content">Col</div></Col>
+        <Col xs={2} sm={4} md={6} lg={8} xl={10}><div className="col-content">Col</div></Col>
+    </Row>
+    <br/>
+    <Row>
+        <Col xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+        <Col xs={{ span: 11, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+        <Col xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 2 }}><div className="col-content">Col</div></Col>
+    </Row>
+  </div>
+)
+```
+
+## API 参考
+
+### Row
+
+| 属性  | 说明  | 类型  | 默认值  |
+| -- | -- | -- | -- |
+| align   | flex 布局下的垂直对齐方式:`top` `middle` `bottom`  | string  | |
+| className | 类名 | string| |
+| gutter  | 栅格间隔,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}`<br />**从1.11.0版本起支持垂直间隔**  | number\|object\|Array<number\|object> | |
+| justify | flex 布局下的水平排列方式:`start` `end` `center` `space-around` `space-between` | string  | `start` |
+| style | 自定义样式 | CSSProperties | |
+| type  | 布局模式,可选 `flex`,[现代浏览器](http://caniuse.com/#search=flex) 下有效  | string   |  |
+
+### Col
+
+| 属性   | 说明  | 类型 | 默认值 |
+| ---- | ----| ---- | ---- |
+| lg     | `≥992px` 响应式栅格,可为栅格数或对象配置  | number\|object | - |
+| md     | `≥768px` 响应式栅格,可为栅格数或对象配置  | number\|object | - |
+| offset | 栅格左侧的间隔格数,间隔内不可以有栅格 | number | 0 |
+| order  | 栅格顺序,`flex` 布局模式下有效  | number | 0 |
+| pull   | 栅格向左移动格数 | number | 0 |
+| push   | 栅格向右移动格数 | number | 0 |
+| sm     | `≥575px` 响应式栅格,可为栅格数或对象配置  | number\|object | - |
+| span   | 栅格占位格数,为 0 时相当于 `display: none` | number | -      |
+| xl     | `≥1200px` 响应式栅格,可为栅格数或对象配置 | number\|object | - |
+| xs     | `<576px` 响应式栅格,可为栅格数或对象配置  | number\|object | - |
+| xxl    | `≥1600px` 响应式栅格,可为栅格数或对象配置 | number\|object | - |
+
+## 设计变量
+<DesignToken/>

+ 161 - 0
content/basic/icon/index-en-US.md

@@ -0,0 +1,161 @@
+---
+localeCode: en-US
+order: 10
+category: Basic
+title: Icon
+subTitle: Icon
+icon: doc-icons
+brief: Semantic vector graphics.
+---
+
+## Icon List
+```icon
+```
+
+## Demos
+
+### How to import
+
+```jsx import
+import Icon, { IconHome } from '@douyinfe/semi-icons';
+```
+
+### Basic usage
+Import icons from the `@douyinfe/semi-icons` package
+
+```jsx live=true
+import React from 'react';
+import { IconHome } from '@douyinfe/semi-icons';
+
+() => <IconHome />;
+
+```
+
+
+### Rotate & Spin
+Introduce icons from the `@douyinfe/semi-icons` package, with its own size, rotation, and spin functions
+
+```jsx live=true
+import React from 'react';
+import { IconHome, IconEmoji, IconSpin } from '@douyinfe/semi-icons';
+
+() => (
+  <div>
+    <IconHome size="small" />
+    <IconEmoji rotate={180} />
+    <IconSpin spin />
+  </div>
+)
+
+```
+
+### Size
+>
+You can change the `font-size` to change the icon size
+>
+
+The Icon component encapsulates the size attribute, which makes it easier to define the icon size. It supports `extra-small` (8x8), `small` (12x12), `default` (16x16), `large` (20x20), `extra-large `(24x24).
+
+
+```jsx live=true
+import React from 'react';
+import { IconSearch, IconHelpCircle, IconAlertCircle, IconMinusCircle, IconPlusCircle, IconPlus, IconRefresh } from '@douyinfe/semi-icons';
+
+() => {
+   const types = [<IconSearch />, <IconHelpCircle />, <IconAlertCircle />, <IconMinusCircle />, <IconPlusCircle />, <IconPlus />, <IconRefresh />];
+   const sizes = ['extra-small', 'small', 'default', 'large', 'extra-large'];
+   let icons = types.map((type, i) => {
+     return <div key={i} style={{ marginBottom: 4 }}>{sizes.map(size => React.cloneElement(type, {size, key:size}))}</div>
+   })
+   return icons;
+}
+```
+
+### Color
+The icon will automatically inherit the `color` property of the external container CSS
+You can also modify the color of the icon by setting style props to the Icon.
+
+```jsx live=true
+import React from 'react';
+import { IconLikeHeart, IconFlag, IconLock, IconUnlock } from '@douyinfe/semi-icons';
+
+() => (
+  <div>
+    <div style={{color:'#E91E63'}} >
+      <IconLikeHeart size="extra-large"/>
+      <IconFlag size="extra-large"/>
+    </div>
+    <br/>
+    <div>
+      <IconLock style={{color:'#6A3AC7'}} size="extra-large" />
+      <IconUnlock style={{color:'#9C27B0'}} size="extra-large"/>
+    </div>
+  </div>
+)
+```
+
+### Custom icon
+You can use custom icons to pass in Icon components
+Icon component supports size, rotate, spinning and other attributes
+
+```jsx live=true
+import React from 'react';
+import { Icon } from '@douyinfe/semi-ui';
+
+() => {
+  function CustomIcon(){
+    return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <circle cx="12" cy="12" r="11" fill="#FBCD2C"/>
+      <mask id="mask0" maskType="alpha" maskUnits="userSpaceOnUse" x="1" y="1" width="22" height="22">
+        <circle cx="12" cy="12" r="11" fill="#A2845E"/>
+      </mask>
+      <g mask="url(#mask0)">
+        <path fillRule="evenodd" clipRule="evenodd" d="M11.9996 17.7963C13.7184 17.7963 15.2479 16.3561 16.0881 14.2048C16.6103 13.9909 17.1072 13.3424 17.334 12.4957C17.629 11.3948 17.5705 10.4118 16.7665 10.1059C16.6885 6.27115 15.1754 4.78714 11.9996 4.78714C8.82412 4.78714 7.31097 6.27097 7.2328 10.1052C6.42711 10.4103 6.36828 11.394 6.66349 12.4957C6.89064 13.3435 7.38849 13.9926 7.91145 14.2056C8.7518 16.3565 10.2811 17.7963 11.9996 17.7963ZM20.0126 23C20.34 23 20.5906 22.7037 20.4686 22.3999C19.6099 20.2625 16.1444 18.6636 12 18.6636C7.85555 18.6636 4.39008 20.2625 3.53142 22.3999C3.40937 22.7037 3.65999 23 3.9874 23H20.0126Z" fill="white"/>
+      </g>
+    </svg>
+  }
+  return (
+  <div>
+    <Icon svg={<CustomIcon />} />
+    <Icon svg={<CustomIcon />} rotate={180} />
+   </div>
+)
+}
+```
+
+### Use svgr to convert svg files into ReactComponent
+If the icons provided by Semi are not enough to meet business needs, you can also introduce custom icons through @svgr/webpack and use them as React components
+
+```
+// webpack.config.js
+{
+  test: /\.svg$/,
+  use: ['@svgr/webpack'],
+}
+
+import { Icon } from '@douyinfe/semi-ui';
+import StarIcon from './star.svg';
+
+<Icon svg={<StarIcon />} />
+```
+
+
+
+## API reference
+
+### Icon
+
+| Properties  | Illustrate        | Type            | Default |
+|-------|-------------|-----------------|--------|
+| className | class name | string | none |
+| onClick | Callback event of clicking the icon | (e: Event) => void | None |
+| onMouseDown | The callback event of mouse button press >=v1.21 | (e: Event) => void | None |
+| onMouseEnter | Callback event of entering icon | (e: Event) => void | None |
+| onMouseLeave | Callback event of leaving icon | (e: Event) => void | None |
+| onMouseMove | Callback event of moving the mouse >=v1.21 | (e: Event) => void | None |
+| onMouseUp | Callback event when the mouse button is raised >=v1.21 | (e: Event) => void | None |
+| rotate | degree of rotation | number | |
+| size | Size, supports `extra-small`, `small`, `default`, `large`, `extra-large` | string | `default` |
+| spin | spin animation | boolean | |
+| style | Icon style | CSSProperties | None |
+| svg | Icon content | ReactNode | None |

+ 160 - 0
content/basic/icon/index.md

@@ -0,0 +1,160 @@
+---
+localeCode: zh-CN
+order: 10
+category: 基础
+title:  Icon 图标
+icon: doc-icons
+brief: 语义化的矢量图形。
+---
+
+## 图标列表
+```icon
+```
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import Icon, { IconHome } from '@douyinfe/semi-icons';
+```
+
+### 基础使用
+从`@douyinfe/semi-icons`包中引入图标
+
+```jsx live=true
+import React from 'react';
+import { IconHome } from '@douyinfe/semi-icons';
+
+() => <IconHome />;
+
+```
+
+
+### 旋转
+从`@douyinfe/semi-icons`包中引入图标,自带尺寸、旋转、spin功能
+
+```jsx live=true
+import React from 'react';
+import { IconHome, IconEmoji, IconSpin } from '@douyinfe/semi-icons';
+
+() => (
+  <div>
+    <IconHome size="small" />
+    <IconEmoji rotate={180} />
+    <IconSpin spin />
+  </div>
+)
+
+```
+
+### 尺寸
+>
+可以改变`font-size`来更改图标大小
+>
+
+Icon组件封装了size属性,可以更方便地定义图标尺寸,支持 `extra-small` (8x8),`small` (12x12), `default` (16x16), `large` (20x20), `extra-large` (24x24)。
+
+
+```jsx live=true
+import React from 'react';
+import { IconSearch, IconHelpCircle, IconAlertCircle, IconMinusCircle, IconPlusCircle, IconPlus, IconRefresh } from '@douyinfe/semi-icons';
+
+() => {
+   const types = [<IconSearch />, <IconHelpCircle />, <IconAlertCircle />, <IconMinusCircle />, <IconPlusCircle />, <IconPlus />, <IconRefresh />];
+   const sizes = ['extra-small', 'small', 'default', 'large', 'extra-large'];
+   let icons = types.map((type, i) => {
+     return <div key={i} style={{ marginBottom: 4 }}>{sizes.map(size => React.cloneElement(type, {size, key:size}))}</div>
+   })
+   return icons;
+}
+```
+
+### 颜色
+图标会自动继承外部容器 CSS 的 `color` 属性
+你还可以通过给 Icon 设置 style props 来修改图标的颜色。
+
+```jsx live=true
+import React from 'react';
+import { IconLikeHeart, IconFlag, IconLock, IconUnlock } from '@douyinfe/semi-icons';
+
+() => (
+  <div>
+    <div style={{color:'#E91E63'}} >
+      <IconLikeHeart size="extra-large"/>
+      <IconFlag size="extra-large"/>
+    </div>
+    <br/>
+    <div>
+      <IconLock style={{color:'#6A3AC7'}} size="extra-large" />
+      <IconUnlock style={{color:'#9C27B0'}} size="extra-large"/>
+    </div>
+  </div>
+)
+```
+
+### 自定义图标
+可以使用自定义图标传入Icon组件
+Icon组件支持size、rotate、spining等属性
+
+```jsx live=true
+import React from 'react';
+import { Icon } from '@douyinfe/semi-ui';
+
+() => {
+  function CustomIcon(){
+    return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <circle cx="12" cy="12" r="11" fill="#FBCD2C"/>
+      <mask id="mask0" maskType="alpha" maskUnits="userSpaceOnUse" x="1" y="1" width="22" height="22">
+        <circle cx="12" cy="12" r="11" fill="#A2845E"/>
+      </mask>
+      <g mask="url(#mask0)">
+        <path fillRule="evenodd" clipRule="evenodd" d="M11.9996 17.7963C13.7184 17.7963 15.2479 16.3561 16.0881 14.2048C16.6103 13.9909 17.1072 13.3424 17.334 12.4957C17.629 11.3948 17.5705 10.4118 16.7665 10.1059C16.6885 6.27115 15.1754 4.78714 11.9996 4.78714C8.82412 4.78714 7.31097 6.27097 7.2328 10.1052C6.42711 10.4103 6.36828 11.394 6.66349 12.4957C6.89064 13.3435 7.38849 13.9926 7.91145 14.2056C8.7518 16.3565 10.2811 17.7963 11.9996 17.7963ZM20.0126 23C20.34 23 20.5906 22.7037 20.4686 22.3999C19.6099 20.2625 16.1444 18.6636 12 18.6636C7.85555 18.6636 4.39008 20.2625 3.53142 22.3999C3.40937 22.7037 3.65999 23 3.9874 23H20.0126Z" fill="white"/>
+      </g>
+    </svg>
+  }
+  return (
+  <div>
+    <Icon svg={<CustomIcon />} />
+    <Icon svg={<CustomIcon />} rotate={180} />
+   </div>
+)
+}
+```
+
+### 使用svgr将svg文件转成ReactComponent
+如果 Semi 提供的图标不足以满足业务需求,你也可以通过@svgr/webpack引入自定义图标,并以React组件形式使用
+
+```
+// webpack.config.js
+{
+  test: /\.svg$/,
+  use: ['@svgr/webpack'],
+}
+
+import { Icon } from '@douyinfe/semi-ui';
+import StarIcon from './star.svg';
+
+<Icon svg={<StarIcon />} />
+```
+
+
+
+## API参考
+
+### Icon
+
+| 属性  | 说明        | 类型            | 默认值 |
+|-------|-------------|-----------------|--------|
+| className | 类名 | string | 无    |
+| onClick | 单击图标的回调事件 | (e: Event) => void | 无    |
+| onMouseDown | 鼠标按钮按下的回调事件 >=v1.21 | (e: Event) => void | 无    |
+| onMouseEnter | 进入图标的回调事件 | (e: Event) => void | 无    |
+| onMouseLeave | 离开图标的回调事件 | (e: Event) => void | 无    |
+| onMouseMove | 移动鼠标的回调事件 >=v1.21 | (e: Event) => void | 无    |
+| onMouseUp | 鼠标按钮抬起的回调事件 >=v1.21 | (e: Event) => void | 无    |
+| rotate | 旋转度数 | number |   |
+| size | 尺寸,支持`extra-small`,`small`, `default`, `large`, `extra-large` | string | `default`  |
+| spin | 旋转动画 | boolean |   |
+| style | 图标样式 | CSSProperties | 无    |
+| svg | 图标内容 | ReactNode | 无    |

+ 506 - 0
content/basic/layout/index-en-US.md

@@ -0,0 +1,506 @@
+---
+localeCode: en-US
+order: 11
+category: Basic
+title:  Layout
+subTitle: Layout
+icon: doc-layout
+dir: column
+brief: Assist in the overall layout of a page.
+---
+
+
+## Overview
+
+-   `Layout`: Layout containers. You can nest `Header` `Sider` `Content` `Footer` or `Layout` itself inside.
+-   `Header`: Head component, can only be used inside `Layout`.
+-   `Sider`: Sidebar, can only be used inside `Layout`.
+-   `Content`: Content component, can only be used inside `Layout`.
+-   `Footer`: Footer component, can only be used inside `Layout`.
+
+> Note: Layout components are implemented with Flex layout. Browser compatibility may need to be considered.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Layout } from '@douyinfe/semi-ui';
+```
+### Three-section Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+  const { Header, Footer, Content } = Layout;
+  return (
+        <Layout className='components-layout-demo'>
+            <Header>Header</Header>
+            <Content>Content</Content>
+            <Footer>Footer</Footer>
+        </Layout>
+    )
+}
+```
+
+### Left-sidebar Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+  const { Header, Footer, Sider, Content } = Layout;
+  return (
+        <Layout className='components-layout-demo'>
+            <Header>Header</Header>
+            <Layout >
+                <Sider>Sider</Sider>
+                <Content>Content</Content>
+            </Layout>
+            <Footer>Footer</Footer>
+        </Layout>
+    )
+}
+```
+
+### Right-sidebar Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+  const { Header, Footer, Sider, Content } = Layout;
+  return (
+        <Layout className='components-layout-demo'>
+            <Header>Header</Header>
+            <Layout >
+                <Content>Content</Content>
+                <Sider>Sider</Sider>
+            </Layout>
+            <Footer>Footer</Footer>
+        </Layout>
+    )
+}
+```
+
+### Sidebar Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+  const { Header, Footer, Sider, Content } = Layout;
+  return (
+        <Layout className='components-layout-demo' >
+            <Sider>Sider</Sider>
+            <Layout>
+                <Header>Header</Header>
+                <Content>Content</Content>
+                <Footer>Footer</Footer>
+            </Layout>
+        </Layout>
+    )
+}
+```
+
+### Responsive Layout
+
+Six response sizes are preset in the sidebar: `xs`,`sm`,`md`,`lg`,`xl`,`xxl`. You can use `breakpoint` to set breakpoints, and use `onBreakpoint` to call callback functions.
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+  const onbreakpoint = (screen, bool) => {
+      console.log(screen, bool);
+  }
+  const { Header, Footer, Sider, Content } = Layout;
+  return (
+      <Layout className='components-layout-demo'>
+        <Header>Header</Header>
+        <Layout >
+          <Sider breakpoint={['md']} onBreakpoint={onbreakpoint}>Sider</Sider>
+          <Content>Content</Content>
+        </Layout>
+        <Footer>Footer</Footer>
+      </Layout>
+  )
+}
+```
+
+## Layout Examples
+
+### Top-nav Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconSemiLogo, IconBell, IconHelpCircle, IconBytedanceLogo, IconHome, IconLive, IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+  const { Header, Footer, Content } = Layout;
+  return (
+        <Layout style={{border: '1px solid var(--semi-color-border)'}}>
+            <Header style={{backgroundColor: 'var(--semi-color-bg-1)'}}>
+              <div>
+                <Nav mode='horizontal' defaultSelectedKeys={['Home']}>
+                  <Nav.Header>
+                    <IconSemiLogo style={{ fontSize: 36 }} />
+                  </Nav.Header>
+                  <Nav.Item itemKey='Home' text='Home' icon={<IconHome size="large" />} />
+                  <Nav.Item itemKey='Live' text='Live' icon={<IconLive size="large" />} />
+                  <Nav.Item itemKey='Setting' text='Setting' icon={<IconSetting size="large" />} />
+                  <Nav.Footer>
+                    <Button
+                      theme="borderless"
+                      icon = {<IconBell size="large"/>}
+                      style={{
+                        color:'var(--semi-color-text-2)',
+                        marginRight: '12px',
+                      }}
+                    />
+                    <Button
+                      theme="borderless"
+                      icon = {<IconHelpCircle size="large"/>}
+                      style={{
+                        color:'var(--semi-color-text-2)',
+                        marginRight: '12px',
+                      }}
+                    />
+                    <Avatar color='orange' size='small'>YJ</Avatar>
+                  </Nav.Footer>
+                </Nav>
+              </div>
+            </Header>
+            <Content
+              style={{
+                padding: '24px',
+                backgroundColor: 'var(--semi-color-bg-0)'
+              }}
+            >
+              <Breadcrumb
+                style={{
+                  marginBottom: '24px'
+                }}
+                routes={['Home', 'Page Section', 'Pagge Ssection', 'Detail']} />
+              <div
+                style={{
+                  borderRadius: '10px',
+                  border: '1px solid var(--semi-color-border)',
+                  height: '376px',
+                  padding: '32px'
+                }}
+              >
+                <Skeleton placeholder={(<Skeleton.Paragraph rows={2}/>)} loading={true}>
+                    <p>Hi, Bytedance dance dance.</p>
+                    <p>Hi, Bytedance dance dance.</p>
+                </Skeleton>
+              </div>
+            </Content>
+            <Footer
+              style={{
+                display: 'flex',
+                justifyContent: 'space-between',
+                padding: '20px',
+                color: 'var(--semi-color-text-2)',
+                backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+              }}
+            >
+              <span
+                style={{
+                  display: 'flex',
+                  alignItems: 'center',
+                }}
+              >
+                <IconBytedanceLogo size='large' style={{marginRight: '8px'}}/>
+                <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+              </span>
+              <span>
+                <span style={{marginRight: '24px'}}>Customer Service</span>
+                <span>Feedback</span>
+              </span>
+            </Footer>
+        </Layout>
+    )
+}
+```
+
+### Top-Nav SideBar Layout
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconSemiLogo, IconBell, IconHelpCircle, IconBytedanceLogo, IconHome, IconHistogram, IconLive, IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout style={{border: '1px solid var(--semi-color-border)'}}>
+            <Header style={{backgroundColor: 'var(--semi-color-bg-1)'}}>
+              <div >
+                 <Nav mode='horizontal' defaultSelectedKeys={['Home']}>
+                  <Nav.Header>
+                    <IconSemiLogo style={{fontSize: 36}} />
+                  </Nav.Header>
+                  <span
+                    style={{
+                      color: 'var(--semi-color-text-2)'
+                    }}
+                  >
+                    <span
+                      style={{
+                        marginRight: '24px',
+                        color: 'var(--semi-color-text-0)',
+                        fontWeight: '600',
+                      }}>Semi Design</span>
+                    <span style={{marginRight: '24px'}}>Semi Theme</span>
+                    <span>Semi Blocks</span>
+                  </span>
+                  <Nav.Footer>
+                    <Button
+                      theme="borderless"
+                      icon = {<IconBell size="large"/>}
+                      style={{
+                        color:'var(--semi-color-text-2)',
+                        marginRight: '12px',
+                      }}
+                    />
+                    <Button
+                      theme="borderless"
+                      icon = {<IconHelpCircle size="large"/>}
+                      style={{
+                        color:'var(--semi-color-text-2)',
+                        marginRight: '12px',
+                      }}
+                    />
+                    <Avatar color='orange' size='small'>YJ</Avatar>
+                  </Nav.Footer>
+                </Nav>
+              </div>
+            </Header>
+            <Layout >
+              <Sider style={{backgroundColor: 'var(--semi-color-bg-1)'}}>
+                  <Nav
+                      style={{ maxWidth: 220, height: '100%' }}
+                      defaultSelectedKeys={['Home']}
+                      items={[
+                          { itemKey: 'Home', text: 'Home', icon: <IconHome size="large" /> },
+                          { itemKey: 'Histogram', text: 'Histogram', icon: <IconHistogram size="large" /> },
+                          { itemKey: 'Live', text: 'Live', icon: <IconLive size="large" /> },
+                          { itemKey: 'Setting', text: 'Setting', icon: <IconSetting size="large" /> },
+                      ]}
+                      footer={{
+                          collapseButton: true,
+                      }}
+                  />
+              </Sider>
+              <Content
+                style={{
+                  padding: '24px',
+                  backgroundColor: 'var(--semi-color-bg-0)'
+                }}
+              >
+                <Breadcrumb
+                  style={{
+                    marginBottom: '24px'
+                  }}
+                  routes={['Home', 'Page Section', 'Ppage Ssection', 'Detail']} />
+                <div
+                  style={{
+                    borderRadius: '10px',
+                    border: '1px solid var(--semi-color-border)',
+                    height: '376px',
+                    padding: '32px'
+                  }}
+                >
+                  <Skeleton placeholder={(<Skeleton.Paragraph rows={2}/>)} loading={true}>
+                      <p>Hi, Bytedance dance dance.</p>
+                      <p>Hi, Bytedance dance dance.</p>
+                  </Skeleton>
+                </div>
+              </Content>
+            </Layout>
+            <Footer
+              style={{
+                display: 'flex',
+                justifyContent: 'space-between',
+                padding: '20px',
+                color: 'var(--semi-color-text-2)',
+                backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+              }}
+            >
+              <span
+                style={{
+                  display: 'flex',
+                  alignItems: 'center',
+                }}
+              >
+                <IconBytedanceLogo size="large" style={{ marginRight: '8px' }} />
+                <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+              </span>
+              <span>
+                <span style={{marginRight: '24px'}}>Customer Service</span>
+                <span>Feedback</span>
+              </span>
+            </Footer>
+        </Layout>
+    )
+}
+```
+
+### SideBar Navigation
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconBell, IconHelpCircle, IconBytedanceLogo, IconHome, IconHistogram, IconLive, IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout style={{border: '1px solid var(--semi-color-border)'}}>
+            <Sider style={{backgroundColor: 'var(--semi-color-bg-1)'}}>
+              <Nav
+                  defaultSelectedKeys={['Home']}
+                  style={{ maxWidth: 220, height: '100%' }}
+                  items={[
+                      { itemKey: 'Home', text: 'Home', icon: <IconHome size="large" /> },
+                      { itemKey: 'Histogram', text: 'Histogram', icon: <IconHistogram size="large" /> },
+                      { itemKey: 'Live', text: 'Live', icon: <IconLive size="large" /> },
+                      { itemKey: 'Setting', text: 'Setting', icon: <IconSetting size="large" /> },
+                  ]}
+                  header={{
+                      logo: <img src="//lf1-cdn-tos.bytescm.com/obj/ttfe/ies/semi/webcast_logo.svg" />,
+                      text: 'Webcast'
+                  }}
+                  footer={{
+                      collapseButton: true,
+                  }}
+              />
+            </Sider>
+            <Layout>
+                <Header style={{backgroundColor: 'var(--semi-color-bg-1)'}}>
+                  <Nav
+                    mode='horizontal'
+                    footer={
+                      <>
+                        <Button
+                          theme="borderless"
+                          icon = {<IconBell size="large" />}
+                          style={{
+                            color:'var(--semi-color-text-2)',
+                            marginRight: '12px',
+                          }}
+                        />
+                        <Button
+                          theme="borderless"
+                          icon = {<IconHelpCircle size="large" />}
+                          style={{
+                            color:'var(--semi-color-text-2)',
+                            marginRight: '12px',
+                          }}
+                        />
+                        <Avatar color='orange' size='small'>YJ</Avatar>
+                      </>
+                    }
+                  >
+                </Nav>
+                </Header>
+                <Content
+                  style={{
+                    padding: '24px',
+                    backgroundColor: 'var(--semi-color-bg-0)'
+                  }}
+                >
+                  <Breadcrumb
+                    style={{
+                      marginBottom: '24px'
+                    }}
+                    routes={['Home', 'Page Section', 'Pagge Ssection', 'Detail']} />
+                  <div
+                    style={{
+                      borderRadius: '10px',
+                      border: '1px solid var(--semi-color-border)',
+                      height: '376px',
+                      padding: '32px'
+                    }}
+                  >
+                    <Skeleton placeholder={(<Skeleton.Paragraph rows={2}/>)} loading={true}>
+                        <p>Hi, Bytedance dance dance.</p>
+                        <p>Hi, Bytedance dance dance.</p>
+                    </Skeleton>
+                  </div>
+                </Content>
+                <Footer
+                  style={{
+                    display: 'flex',
+                    justifyContent: 'space-between',
+                    padding: '20px',
+                    color: 'var(--semi-color-text-2)',
+                    backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+                  }}
+                >
+                  <span
+                    style={{
+                      display: 'flex',
+                      alignItems: 'center',
+                    }}
+                  >
+                    <IconBytedanceLogo size="large" style={{ marginRight: '8px' }} />
+                    <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+                  </span>
+                  <span>
+                    <span style={{marginRight: '24px'}}>Customer Service</span>
+                    <span>Feedback</span>
+                  </span>
+                </Footer>
+            </Layout>
+        </Layout>
+    )
+}
+```
+
+## API Reference
+
+### Layout
+
+> `Layout.Header`, `Layout.Footer`, `Layout.Content` use same API as `Layout`
+
+| Properties | Instructions                                                                                                                               | type    | Default |
+| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- | ------- |
+| className  | Class name                                                                                                                                 | string  | -       |
+| hasSider   | Indicates that there is a Sider in the child element, which is generally not specified. It can be used to avoid style flashing during SSR. | boolean | -       |
+| style      | Style                                                                                                                                      | CSSProperties  | -       |
+
+### Layout.Sider
+
+| Properties   | Instructions                                                                           | type                                 | Default |
+| ------------ | -------------------------------------------------------------------------------------- | ------------------------------------ | ------- |
+| breakpoint   | Breakpoints that trigger responsive layout, one of 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' | String[]                             | -       |
+| className    | Class name                                                                             | string                               | -       |
+| style        | Style                                                                                  | CSSProperties                               | -       |
+| onBreakpoint | Callback function when triggering a responsive layout breakpoint                       | (screen: string, broken: bool) => void | -       |
+
+### responsive map
+
+```jsx
+{
+  xs: '(max-width: 575px)',
+  sm: '(min-width: 576px)',
+  md: '(min-width: 768px)',
+  lg: '(min-width: 992px)',
+  xl: '(min-width: 1200px)',
+  xxl: '(min-width: 1600px)',
+}
+```
+
+<!-- ## Related Material
+```material
+2, 43
+``` -->

+ 520 - 0
content/basic/layout/index.md

@@ -0,0 +1,520 @@
+---
+localeCode: zh-CN
+order: 11
+category: 基础
+title: Layout 布局
+icon: doc-layout
+dir: column
+brief: 协助进行页面级整体布局。
+---
+
+## 概述
+
+-   `Layout`:布局容器,其下可嵌套 `Header` `Sider` `Content` `Footer` 或 `Layout` 本身,可以放在任何父容器中。
+-   `Header`:顶部布局,其下可嵌套任何元素,只能放在 `Layout` 中。
+-   `Sider`:侧边栏,其下可嵌套任何元素,只能放在 `Layout` 中。
+-   `Content`:内容部分,其下可嵌套任何元素,只能放在 `Layout` 中。
+-   `Footer`:底部布局,其下可嵌套任何元素,只能放在 `Layout` 中。
+
+> 注意:布局组件采用 Flex 布局实现,需要考虑浏览器兼容性问题。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Layout } from '@douyinfe/semi-ui';
+```
+
+### 三行布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+    const { Header, Footer, Content } = Layout;
+
+    return (
+        <Layout className="components-layout-demo">
+            <Header>Header</Header>
+            <Content>Content</Content>
+            <Footer>Footer</Footer>
+        </Layout>
+    );
+};
+```
+
+### 左侧边栏布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout className="components-layout-demo">
+            <Header>Header</Header>
+            <Layout>
+                <Sider>Sider</Sider>
+                <Content>Content</Content>
+            </Layout>
+            <Footer>Footer</Footer>
+        </Layout>
+    );
+};
+```
+
+### 右侧边栏布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout className="components-layout-demo">
+            <Header>Header</Header>
+            <Layout>
+                <Content>Content</Content>
+                <Sider>Sider</Sider>
+            </Layout>
+            <Footer>Footer</Footer>
+        </Layout>
+    );
+};
+```
+
+### 侧边栏布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout className="components-layout-demo">
+            <Sider>Sider</Sider>
+            <Layout>
+                <Header>Header</Header>
+                <Content>Content</Content>
+                <Footer>Footer</Footer>
+            </Layout>
+        </Layout>
+    );
+};
+```
+
+### 响应式布局
+
+侧边栏预设了六个响应尺寸:`xs`、`sm`、`md`、`lg`、`xl`、`xxl`。可以通过设置 `breakpoint` 属性设置断点,通过 `onBreakpoint` 调用回调函数。
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout } from '@douyinfe/semi-ui';
+
+() => {
+    const onbreakpoint = (screen, bool) => {
+        console.log(screen, bool);
+    };
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout className="components-layout-demo">
+            <Header>Header</Header>
+            <Layout>
+                <Sider breakpoint={['md']} onBreakpoint={onbreakpoint}>
+                    Sider
+                </Sider>
+                <Content>Content</Content>
+            </Layout>
+            <Footer>Footer</Footer>
+        </Layout>
+    );
+};
+```
+
+## 布局示例
+
+### 顶部导航布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconSemiLogo, IconBell, IconHelpCircle, IconBytedanceLogo,IconHome,IconLive,IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+    const { Header, Footer, Content } = Layout;
+    return (
+        <Layout style={{ border: '1px solid var(--semi-color-border)' }}>
+            <Header style={{ backgroundColor: 'var(--semi-color-bg-1)' }}>
+                <div>
+                    <Nav mode="horizontal" defaultSelectedKeys={['Home']}>
+                        <Nav.Header>
+                            <IconSemiLogo style={{ fontSize: 36 }} />
+                        </Nav.Header>
+                        <Nav.Item itemKey="Home" text="首页" icon={<IconHome size="large" />} />
+                        <Nav.Item itemKey="Live" text="直播" icon={<IconLive size="large" />} />
+                        <Nav.Item itemKey="Setting" text="设置" icon={<IconSetting size="large" />} />
+                        <Nav.Footer>
+                            <Button
+                                theme="borderless"
+                                icon={<IconBell size="large" />}
+                                style={{
+                                    color: 'var(--semi-color-text-2)',
+                                    marginRight: '12px',
+                                }}
+                            />
+                            <Button
+                                theme="borderless"
+                                icon={<IconHelpCircle size="large" />}
+                                style={{
+                                    color: 'var(--semi-color-text-2)',
+                                    marginRight: '12px',
+                                }}
+                            />
+                            <Avatar color="orange" size="small">
+                                YJ
+                            </Avatar>
+                        </Nav.Footer>
+                    </Nav>
+                </div>
+            </Header>
+            <Content
+                style={{
+                    padding: '24px',
+                    backgroundColor: 'var(--semi-color-bg-0)',
+                }}
+            >
+                <Breadcrumb
+                    style={{
+                        marginBottom: '24px',
+                    }}
+                    routes={['首页', '当这个页面标题很长时需要省略', '上一页', '详情页']}
+                />
+                <div
+                    style={{
+                        borderRadius: '10px',
+                        border: '1px solid var(--semi-color-border)',
+                        height: '376px',
+                        padding: '32px',
+                    }}
+                >
+                    <Skeleton placeholder={<Skeleton.Paragraph rows={2} />} loading={true}>
+                        <p>Hi, Bytedance dance dance.</p>
+                        <p>Hi, Bytedance dance dance.</p>
+                    </Skeleton>
+                </div>
+            </Content>
+            <Footer
+                style={{
+                    display: 'flex',
+                    justifyContent: 'space-between',
+                    padding: '20px',
+                    color: 'var(--semi-color-text-2)',
+                    backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+                }}
+            >
+                <span
+                    style={{
+                        display: 'flex',
+                        alignItems: 'center',
+                    }}
+                >
+                    <IconBytedanceLogo size="large" style={{ marginRight: '8px' }} />
+                    <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+                </span>
+                <span>
+                    <span style={{ marginRight: '24px' }}>平台客服</span>
+                    <span>反馈建议</span>
+                </span>
+            </Footer>
+        </Layout>
+    );
+};
+```
+
+### 顶部导航-侧边布局
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconSemiLogo, IconBell, IconHelpCircle, IconBytedanceLogo, IconHome, IconHistogram, IconLive, IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout style={{ border: '1px solid var(--semi-color-border)' }}>
+            <Header style={{ backgroundColor: 'var(--semi-color-bg-1)' }}>
+                <div>
+                    <Nav mode="horizontal" defaultSelectedKeys={['Home']}>
+                        <Nav.Header>
+                            <IconSemiLogo style={{ width: '96px', height: '36px', fontSize: 36 }} />
+                        </Nav.Header>
+                        <span
+                            style={{
+                                color: 'var(--semi-color-text-2)',
+                            }}
+                        >
+                            <span
+                                style={{
+                                    marginRight: '24px',
+                                    color: 'var(--semi-color-text-0)',
+                                    fontWeight: '600',
+                                }}
+                            >
+                                模版推荐
+                            </span>
+                            <span style={{ marginRight: '24px' }}>所有模版</span>
+                            <span>我的模版</span>
+                        </span>
+                        <Nav.Footer>
+                            <Button
+                                theme="borderless"
+                                icon={<IconBell size="large" />}
+                                style={{
+                                    color: 'var(--semi-color-text-2)',
+                                    marginRight: '12px',
+                                }}
+                            />
+                            <Button
+                                theme="borderless"
+                                icon={<IconHelpCircle size="large" />}
+                                style={{
+                                    color: 'var(--semi-color-text-2)',
+                                    marginRight: '12px',
+                                }}
+                            />
+                            <Avatar color="orange" size="small">
+                                YJ
+                            </Avatar>
+                        </Nav.Footer>
+                    </Nav>
+                </div>
+            </Header>
+            <Layout>
+                <Sider style={{ backgroundColor: 'var(--semi-color-bg-1)' }}>
+                    <Nav
+                        style={{ maxWidth: 220, height: '100%' }}
+                        defaultSelectedKeys={['Home']}
+                        items={[
+                            { itemKey: 'Home', text: '首页', icon: <IconHome size="large" /> },
+                            { itemKey: 'Histogram', text: '基础数据', icon: <IconHistogram size="large" /> },
+                            { itemKey: 'Live', text: '测试功能', icon: <IconLive size="large" /> },
+                            { itemKey: 'Setting', text: '设置', icon: <IconSetting size="large" /> },
+                        ]}
+                        footer={{
+                            collapseButton: true,
+                        }}
+                    />
+                </Sider>
+                <Content
+                    style={{
+                        padding: '24px',
+                        backgroundColor: 'var(--semi-color-bg-0)',
+                    }}
+                >
+                    <Breadcrumb
+                        style={{
+                            marginBottom: '24px',
+                        }}
+                        routes={['首页', '当这个页面标题很长时需要省略', '上一页', '详情页']}
+                    />
+                    <div
+                        style={{
+                            borderRadius: '10px',
+                            border: '1px solid var(--semi-color-border)',
+                            height: '376px',
+                            padding: '32px',
+                        }}
+                    >
+                        <Skeleton placeholder={<Skeleton.Paragraph rows={2} />} loading={true}>
+                            <p>Hi, Bytedance dance dance.</p>
+                            <p>Hi, Bytedance dance dance.</p>
+                        </Skeleton>
+                    </div>
+                </Content>
+            </Layout>
+            <Footer
+                style={{
+                    display: 'flex',
+                    justifyContent: 'space-between',
+                    padding: '20px',
+                    color: 'var(--semi-color-text-2)',
+                    backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+                }}
+            >
+                <span
+                    style={{
+                        display: 'flex',
+                        alignItems: 'center',
+                    }}
+                >
+                    <IconBytedanceLogo size="large" style={{ marginRight: '8px' }} />
+                    <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+                </span>
+                <span>
+                    <span style={{ marginRight: '24px' }}>平台客服</span>
+                    <span>反馈建议</span>
+                </span>
+            </Footer>
+        </Layout>
+    );
+};
+```
+
+### 侧边导航
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Layout, Nav, Button, Breadcrumb, Skeleton, Avatar } from '@douyinfe/semi-ui';
+import { IconBell, IconHelpCircle, IconBytedanceLogo, IconHome, IconHistogram, IconLive, IconSetting } from '@douyinfe/semi-icons';
+
+() => {
+    const { Header, Footer, Sider, Content } = Layout;
+    return (
+        <Layout style={{ border: '1px solid var(--semi-color-border)' }}>
+            <Sider style={{ backgroundColor: 'var(--semi-color-bg-1)' }}>
+                <Nav
+                    defaultSelectedKeys={['Home']}
+                    style={{ maxWidth: 220, height: '100%' }}
+                    items={[
+                        { itemKey: 'Home', text: '首页', icon: <IconHome size="large" /> },
+                        { itemKey: 'Histogram', text: '基础数据', icon: <IconHistogram size="large" /> },
+                        { itemKey: 'Live', text: '测试功能', icon: <IconLive size="large" /> },
+                        { itemKey: 'Setting', text: '设置', icon: <IconSetting size="large" /> },
+                    ]}
+                    header={{
+                        logo: <img src="//lf1-cdn-tos.bytescm.com/obj/ttfe/ies/semi/webcast_logo.svg" />,
+                        text: '直播运营后台',
+                    }}
+                    footer={{
+                        collapseButton: true,
+                    }}
+                />
+            </Sider>
+            <Layout>
+                <Header style={{ backgroundColor: 'var(--semi-color-bg-1)' }}>
+                    <Nav
+                        mode="horizontal"
+                        footer={
+                            <>
+                                <Button
+                                    theme="borderless"
+                                    icon={<IconBell size="large" />}
+                                    style={{
+                                        color: 'var(--semi-color-text-2)',
+                                        marginRight: '12px',
+                                    }}
+                                />
+                                <Button
+                                    theme="borderless"
+                                    icon={<IconHelpCircle size="large" />}
+                                    style={{
+                                        color: 'var(--semi-color-text-2)',
+                                        marginRight: '12px',
+                                    }}
+                                />
+                                <Avatar color="orange" size="small">
+                                    YJ
+                                </Avatar>
+                            </>
+                        }
+                    ></Nav>
+                </Header>
+                <Content
+                    style={{
+                        padding: '24px',
+                        backgroundColor: 'var(--semi-color-bg-0)',
+                    }}
+                >
+                    <Breadcrumb
+                        style={{
+                            marginBottom: '24px',
+                        }}
+                        routes={['首页', '当这个页面标题很长时需要省略', '上一页', '详情页']}
+                    />
+                    <div
+                        style={{
+                            borderRadius: '10px',
+                            border: '1px solid var(--semi-color-border)',
+                            height: '376px',
+                            padding: '32px',
+                        }}
+                    >
+                        <Skeleton placeholder={<Skeleton.Paragraph rows={2} />} loading={true}>
+                            <p>Hi, Bytedance dance dance.</p>
+                            <p>Hi, Bytedance dance dance.</p>
+                        </Skeleton>
+                    </div>
+                </Content>
+                <Footer
+                    style={{
+                        display: 'flex',
+                        justifyContent: 'space-between',
+                        padding: '20px',
+                        color: 'var(--semi-color-text-2)',
+                        backgroundColor: 'rgba(var(--semi-grey-0), 1)',
+                    }}
+                >
+                    <span
+                        style={{
+                            display: 'flex',
+                            alignItems: 'center',
+                        }}
+                    >
+                        <IconBytedanceLogo size="large" style={{ marginRight: '8px' }} />
+                        <span>Copyright © 2019 ByteDance. All Rights Reserved. </span>
+                    </span>
+                    <span>
+                        <span style={{ marginRight: '24px' }}>平台客服</span>
+                        <span>反馈建议</span>
+                    </span>
+                </Footer>
+            </Layout>
+        </Layout>
+    );
+};
+```
+
+## API 参考
+
+### Layout
+
+> `Layout.Header` `Layout.Footer` `Layout.Content` API 与 `Layout` 相同
+
+| 属性      | 说明                                                               | 类型    | 默认值 |
+| --------- | ------------------------------------------------------------------ | ------- | ------ |
+| className | 类名                                                               | string  | -      |
+| hasSider  | 表示子元素里有 Sider,一般不用指定。可用于服务端渲染时避免样式闪动 | boolean | -      |
+| style     | 样式                                                               | CSSProperties  | -      |
+
+### Layout.Sider
+
+| 属性 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| breakpoint | 触发响应式布局的断点,可选值'xs', 'sm', 'md', 'lg', 'xl', 'xxl' | string[] | - |
+| className | 类名 | string | - |
+| style | 样式 | CSSProperties | - |
+| onBreakpoint | 触发响应式布局断点时的回调 | (screen: string, broken: bool) => void | - |
+
+### responsive map
+
+```jsx
+{
+  xs: '(max-width: 575px)',
+  sm: '(min-width: 576px)',
+  md: '(min-width: 768px)',
+  lg: '(min-width: 992px)',
+  xl: '(min-width: 1200px)',
+  xxl: '(min-width: 1600px)',
+}
+```
+
+<!-- ## 相关物料
+
+```material
+2, 43
+``` -->

+ 179 - 0
content/basic/space/index-en-US.md

@@ -0,0 +1,179 @@
+---
+localeCode: en-US
+order: 13
+category: basic
+title:  Space
+icon: doc-space
+brief: Set the spacing between components.
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Space } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button, Switch } from '@douyinfe/semi-ui';
+
+() => (
+    <Space>
+        <Switch defaultChecked={true}/>     
+        <Button type="secondary">secondary</Button>
+        <Button type="tertiary">tertiary</Button>
+        <Button type="warning">warning</Button>
+    </Space>
+)
+```
+
+### Alignment
+
+You can use `align` to set the alignment, optional: `start`, `center`(default), `end`, `baseline`.
+
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button, Tag } from '@douyinfe/semi-ui';
+
+() => {
+    const divStyle = {
+        width:80,
+        height:100,
+        lineHight:100,
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent:'center',
+        border:'1px solid var(--semi-color-border)',
+        borderRadius: 3
+    };
+    return (
+        <Space vertical>
+            <Space align='start'>
+                <div style={divStyle}> text </div>
+                <Button theme='solid' type='primary'>button</Button>
+                <Tag color='green' size='large'> tag </Tag>
+            </Space>
+            <Space align='center'>
+                <div style={divStyle}> text </div>
+                <Button theme='solid' type='primary'>button</Button>
+                <Tag color='green' size='large'> tag </Tag>
+            </Space>
+            <Space align='end'>
+                <div style={divStyle}> text </div>
+                <Button theme='solid' type='primary'>button</Button>
+                <Tag color='green' size='large'> tag </Tag>
+            </Space>
+            <Space align='baseline'>
+                <div style={divStyle}> text </div>
+                <Button theme='solid' type='primary'>button</Button>
+                <Tag color='green' size='large'> tag </Tag>
+            </Space>
+        </Space>
+    )
+}
+```
+
+### Spacing
+
+You can use `spacing` to set the spacing size, optional: `tight` (8px, defalut), `medium` (16px), `loose` (24px), and allow to pass in number to customize the spacing size, and also support to pass in array to set the horizontal and vertical spacing at the same time.
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Tabs, TabPane, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Tabs type="line">
+        <TabPane tab="tight" itemKey="1">
+            <Space spacing='tight' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="medium" itemKey="2">
+            <Space spacing='medium' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="loose" itemKey="3">
+            <Space spacing='loose' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="array" itemKey="4">
+            <Space spacing={[8,16]} wrap style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+                <Button theme='solid' type='primary'>button</Button>
+            </Space>
+        </TabPane>
+    </Tabs>
+)
+```
+
+### Direction
+
+You can use `vertical` to set whether the spacing is vertical, the default is false.
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Space vertical>
+        <Button theme='solid' type='primary'>button</Button>
+        <Button theme='solid' type='primary'>button</Button>
+        <Button theme='solid' type='primary'>button</Button>
+        <Button theme='solid' type='primary'>button</Button>
+    </Space>
+)
+```
+
+### Wrap
+
+When the spacing is horizontal,you can use `wrap` to set whether to wrap automatically, the default is false.
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Space wrap>
+        {new Array(10).fill(null).map((item, idex) => (
+            <Button theme='solid' type='secondary' key={idex}>button</Button>
+        ))}
+    </Space>
+)
+```
+
+## API Reference
+
+|Properties|Instructions|Type|Default|Version|
+|-|-|-|-|-|
+|align|Alignment, optional:  `start`、`end`、`center`、`baseline`|string|`center`|>=1.17.0|
+|className|Class name|string|-|>=1.17.0|
+|spacing|The space size, optional:  `loose`、`medium`、`tight` 、number and array|string\|number\|array|`medium`|>=1.17.0|
+|style|Inline style|CSSProperties|-|>=1.17.0|
+|vertical|Set to vertical spacing|boolean|false|>=1.17.0|
+|wrap|Whether to wrap|boolean|false|>=1.17.0|
+
+## Design Tokens
+<DesignToken/>

+ 177 - 0
content/basic/space/index.md

@@ -0,0 +1,177 @@
+---
+localeCode: zh-CN
+order: 13
+category: 基础
+title:  Space 间距
+icon: doc-space
+brief: 设置组件之间的间距。
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Space } from '@douyinfe/semi-ui';
+```
+### 基本用法
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button, Switch } from '@douyinfe/semi-ui';
+
+() => (
+    <Space>
+        <Switch defaultChecked={true}/>     
+        <Button type="secondary">次要</Button>
+        <Button type="tertiary">第三</Button>
+        <Button type="warning">警告</Button>
+    </Space>
+)
+```
+### 对齐方式
+
+可使用 `align` 设置对齐方式,可选值:`start`、`center`(默认)、`end`、`baseline`。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button, Tag } from '@douyinfe/semi-ui';
+
+() => {
+    const divStyle = {
+        width:80,
+        height:100,
+        lineHight:100,
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent:'center',
+        border:'1px solid var(--semi-color-border)',
+        borderRadius: 3
+    };
+    return (
+        <Space vertical>
+            <Space align='start'>
+                <div style={divStyle}>文本</div>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Tag color='green' size='large'>标签</Tag>
+            </Space>
+            <Space align='center'>
+                <div style={divStyle}>文本</div>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Tag color='green' size='large'>标签</Tag>
+            </Space>
+            <Space align='end'>
+                <div style={divStyle}>文本</div>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Tag color='green' size='large'>标签</Tag>
+            </Space>
+            <Space align='baseline'>
+                <div style={divStyle}>文本</div>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Tag color='green' size='large'>标签</Tag>
+            </Space>
+        </Space>
+    )
+}
+```
+
+### 间距尺寸
+
+可使用 `spacing` 设置间距大小,内置可选值:`tight`(8px,默认)、`medium`(16px)、`loose`(24px),并且支持传入 number 来自定义间距大小,也支持传入 array 来同时设置水平和垂直方向的间距。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Tabs, TabPane, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Tabs type="line">
+        <TabPane tab="tight" itemKey="1">
+            <Space spacing='tight' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="medium" itemKey="2">
+            <Space spacing='medium' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="loose" itemKey="3">
+            <Space spacing='loose' style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+            </Space>
+        </TabPane>
+        <TabPane tab="array" itemKey="4">
+            <Space spacing={[8,16]} wrap style={{marginTop:'15px'}}>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+                <Button theme='solid' type='primary'>按钮</Button>
+            </Space>
+        </TabPane>
+    </Tabs>
+)
+```
+
+### 间距方向
+
+可使用 `vertical` 设置间距是否为垂直方向,默认情况下为 false。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Space vertical>
+        <Button theme='solid' type='primary'>按钮</Button>
+        <Button theme='solid' type='primary'>按钮</Button>
+        <Button theme='solid' type='primary'>按钮</Button>
+        <Button theme='solid' type='primary'>按钮</Button>
+    </Space>
+)
+```
+
+### 设置换行
+
+当间距为水平方向时,可使用 `wrap` 设置是否自动换行,默认情况下为 false。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Space, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Space wrap>
+        {new Array(10).fill(null).map((item, idex) => (
+            <Button theme='solid' type='secondary' key={idex}>按钮</Button>
+        ))}
+    </Space>
+)
+```
+
+## API参考
+
+|属性|说明|类型|默认值|版本|
+|-|-|-|-|-|
+|align|对齐方式, 支持 `start`、`end`、`center`、`baseline`|string|`center`|>=1.17.0|
+|className|样式类名|string|-|>=1.17.0|
+|spacing|间距尺寸, 支持 `loose`、`medium`、`tight` 或 number、array|string\|number\|array|`tight`|>=1.17.0|
+|style|内联样式|CSSProperties|-|>=1.17.0|
+|vertical|是否为垂直间距|boolean|false|>=1.17.0|
+|wrap|是否自动换行|boolean|false|>=1.17.0|
+
+## 设计变量
+<DesignToken/>

+ 213 - 0
content/basic/tokens/index-en-US.md

@@ -0,0 +1,213 @@
+---
+localeCode: en-US
+order: 12
+category: Basic
+title: Tokens 
+icon: doc-token
+brief: Semi Design Tokens
+---
+
+<JumpToToken/>
+
+## Why use variables
+
+Variables actually decouple the basic elements of design from specific styles.
+For designers, if the style of the product needs to be updated iteratively, for example, the dangerous function color, namely color danger, needs to be updated, they only need to modify its corresponding color default value to complete the UI iteration of the whole product.
+For R &amp; D, in order to adapt to the iteration of product style update, design token can update the style of all components more quickly without modifying everywhere. This is why we need to pay special attention to using variables instead of fixed default values in the development process. If the style of the product is shared by multiple platforms, it can get twice the result with half the effort.
+In particular, for platforms with dark mode requirements, semi design's color variable is needed to achieve the effect of one click switching between light and dark. Therefore, here we will introduce the design token system of semi design in detail and how to use them.
+
+## Basic color
+
+Based on the dynamic generation of brand color, including 160 colors, 16 different hue gradient color disk. In general, we use the color in the base color to further define the function color. You can use your brand color in the theme store to dynamically generate a new basic color disk.
+<FullPalette/>
+
+### Color conversion
+
+<ColorConverter/>
+
+## Functional color
+
+From the basic color disk reference, including the interface background, text icons, links, stroke and other user interface elements.
+
+### Primary color
+
+User interface main tone and interactive colors, usually used for main operation button, etc
+
+<DesignToken componentName='global' reg={/color-primary/}/>
+
+### Secondary color - Secondary
+
+Secondary color - Secondary
+
+<DesignToken componentName='global' reg={/color-secondary/}/>
+
+### The third color - Tertiary
+
+In the user interface, non emphasis color and interactive color are usually used for general and non emphasis function operation buttons
+
+<DesignToken componentName='global' reg={/color-tertiary/}/>
+
+### Information - info
+
+It is usually used to express objective and neutral information in the context with the above semantics
+
+<DesignToken componentName='global' reg={/color-info/}/>
+
+### Success - success
+
+It is usually used to express the success, completion and opening status, and is used in scenarios with the above semantics
+
+<DesignToken componentName='global' reg={/color-success/}/>
+
+### Warning
+
+It is usually used to express warning and unsafe state, and is used in scenarios with the above semantics
+
+<DesignToken componentName='global' reg={/color-warning/}/>
+
+### Danger - danger
+
+It is usually used to express the dangerous state, and is used in the scene with the above semantics
+
+<DesignToken componentName='global' reg={/color-danger/}/>
+
+### Text and icon colors - text
+
+Four different levels of text / icon colors represent the most important, secondary, minor and minor contents in the product interface
+
+<DesignToken componentName='global' reg={/color-text/}/>
+
+### Link color
+
+Text used for hyperlinks in products
+
+<DesignToken componentName='global' reg={/color-link/}/>
+
+### Background color - BG
+
+All levels of background color in the application, including container, menu, navigation bar, etc. In dark mode, we usually use the background color to distinguish the front and back levels
+
+<DesignToken componentName='global' reg={/color-bg/}/>
+
+### Fill color - fill
+
+For an element, if the background color of its container is not fixed, and the contrast between the filling color of the element and the top background color is small, use the filling color as the background color to ensure that the element will not "melt" into a certain level of background color, such as a form control.
+
+<DesignToken componentName='global' reg={/color-fill/}/>
+
+### Stroke border
+
+Color with stroke attribute in interface
+
+<DesignToken componentName='global' reg={/color-border/}/>
+
+### Disabled state - Disabled
+
+It is used to fill all kinds of forbidden elements in the interface, such as background, text, stroke, fill, etc
+
+<DesignToken componentName='global' reg={/color-disabled/}/>
+
+### Constant color static
+
+The interface does not follow the theme and light and dark mode switching color
+
+<DesignToken componentName='global' reg={/((--semi-black)|(--semi-white))$/}/>
+
+### Quasi shadow color - Shadow
+
+Shallow shadow, a flat shadow effect simulated by border, is mainly used in the table component
+
+<DesignToken componentName='global' reg={/^--semi-color-shadow$/}/>
+
+## Typesetting
+
+Typesetting is used to convey information content, and the interface looks orderly
+
+### Trade name
+
+Determines the size of different levels of text
+
+<DesignToken componentName='global' reg={/font-size/}/>
+
+### Word weight
+
+Determine the thickness of different levels of text
+
+<DesignToken componentName='global' reg={/font-weight/}/>
+
+### Font
+
+In order to reduce the packing volume, the default English font inter needs to be introduced separately
+
+If you want to use it on the business side, you need to add a font face statement in your CSS (it is not included in semi, because the font is slightly larger, and the default loading may affect the speed of the first screen of the business). It is up to the business to decide whether to use it or not.
+
+```css
+@font-face {
+  font-family: "Inter";
+  src: url("https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/slepweh7nupqpognuhbo/Inter-Regular.ttf") format("ttf"),
+}
+
+@font-face {
+  font-family: "Inter-Bold";
+  src: url("https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/slepweh7nupqpognuhbo/Inter-Bold.ttf") format("ttf"),
+}
+
+```
+
+
+<DesignToken componentName='global' reg={/font-family/}/>
+
+## Fillet
+
+Fillet is used to describe the outline of container and interface elements, which determines the visual tonality of product to a certain extent
+
+<DesignToken componentName='global' reg={/border-radius/}/>
+
+## Shadow
+
+Shadow is usually used to express the level of interface elements. The heavier the shadow, the closer the element is to the user
+
+<DesignToken componentName='global' reg={/\$shadow/}/>
+
+## Dimensions
+
+The size variable is used in various components and internal elements to adjust the size of the control, stroke thickness, icon size, etc
+
+### Height
+
+<DesignToken componentName='global' reg={/\height-control/}/>
+
+### Stroke size
+
+<DesignToken componentName='global' reg={/\$border-thickness/}/>
+
+### Icon size
+
+<DesignToken componentName='global' reg={/\$width-icon/}/>
+
+## Spacing
+
+The spacing variable is applied in each component or between components to adjust the density and compactness of the whole product
+
+<DesignToken componentName='global' reg={/(spacing-)|(width-base)|(loose)/}/>
+
+## z-index
+
+It is used to describe the sequence of interface elements
+
+<DesignToken componentName='global' reg={/z-/}/>
+
+## Variables not yet supported
+
+Currently, semi does not support global variables in the following categories. If you have related requirements, you can give feedback through issue and describe your expected needs in detail.
+
+**Line height**
+
+**Letter spacing**
+
+**Duration**
+
+**Media query**
+
+## Customization
+If you need to customize the global variable style, please go to [Semi DSM](https://semi.design/dsm), make your own theme and publish it

+ 217 - 0
content/basic/tokens/index.md

@@ -0,0 +1,217 @@
+---
+localeCode: zh-CN
+order: 12
+category: 基础
+title:  Tokens 设计变量
+icon: doc-token
+brief: Semi Design Tokens
+---
+
+<JumpToToken/>
+
+## 为什么要使用变量
+
+变量实际上是将设计中的基础元素与具体的样式进行解耦。
+
+对于设计师来说,如果产品的风格需要迭代更新,比如需要更新 危险 的功能色,即 color-danger,只需要修改其对应的颜色默认值,既可以完成整套产品的 UI 迭代。
+
+对于研发来说,为了配合产品风格的更新迭代,使用 Design Token 时可以更快速地完成所有组件的样式更新,而无需一处处地进行修改,这也是为什么在开发的过程尤其需要注意使用变量而不是固定的数默认值。如果产品的风格有多个平台共用的话,也能事半功倍。
+
+特别地,对于有暗色模式需求的平台,需要使用 Semi Design 的颜色变量才能实现一键切换明暗色的效果。因此这里向大家详细地介绍 Semi Design 的 Design Token 体系以及如何使用它们。
+
+
+
+## 基础色
+
+基于品牌色动态生成,包含 160 个颜色在内的,16 个不同色相的梯度色盘。通常情况下,我们用使用基础色中的颜色来进一步定义功能色。你可以在主题商店动用你的产品品牌色,动态生成新的基础色盘。
+
+<FullPalette/>
+
+### 颜色转换
+<ColorConverter/>
+
+## 功能色
+
+从基础色盘中引用,应用在包括界面背景,文本图标,链接,描边在内的各类用户界面元素上。
+
+### 主要颜色 - primary
+
+用户界面主强调色及各交互态颜色,通常用于主操作按钮等
+
+<DesignToken componentName='global' reg={/color-primary/}/>
+
+### 次要颜色 - secondary
+
+次要颜色 - secondary
+
+<DesignToken componentName='global' reg={/color-secondary/}/>
+
+### 第三颜色 - tertiary
+
+用户界面中非强调色及各交互态颜色,通常用于常规、非强调功能操作按钮等
+
+<DesignToken componentName='global' reg={/color-tertiary/}/>
+
+### 信息 - info
+
+通常用于表达客观、中立信息,在带有上述语义的场景下使用
+
+<DesignToken componentName='global' reg={/color-info/}/>
+
+### 成功 - success
+
+通常用于表达成功、完成、开启状态,在带有上述语义的场景下使用
+
+<DesignToken componentName='global' reg={/color-success/}/>
+
+### 警示 - warning
+
+通常用于表达警告、不安全状态,在带有上述语义的场景下使用
+
+<DesignToken componentName='global' reg={/color-warning/}/>
+
+### 危险 - danger
+
+通常用于表达危险状态,在带有上述语义的场景下使用
+
+<DesignToken componentName='global' reg={/color-danger/}/>
+
+### 文本与图标颜色 - text
+
+四个不同层级的文本/图标颜色,依次代表产品界面中最主要、次主要、稍次要和最次要的内容
+
+<DesignToken componentName='global' reg={/color-text/}/>
+
+### 链接色 - link
+
+用于产品中超链接的文本
+
+<DesignToken componentName='global' reg={/color-link/}/>
+
+### 背景色 - bg
+
+应用中各级背景色,包括容器、菜单、导航栏等。在暗色模式下,我们通常用背景色来区分前后层级
+
+<DesignToken componentName='global' reg={/color-bg/}/>
+
+### 填充色 - fill
+
+对于一个元素,如果其所处的容器背景颜色不固定,且这个元素的填充色与最上层背景色的对比度比较小,使用填充色作为 backgroundColor,确保这个元素不会“融于”某一级别背景颜色中,如表单控件。
+
+<DesignToken componentName='global' reg={/color-fill/}/>
+
+### 描边色 - border
+
+界面中带有描边属性的颜色
+
+<DesignToken componentName='global' reg={/color-border/}/>
+
+### 禁用态 - disabled
+
+用于界面中各类表达禁用的元素填充,如背景、文本、描边、填充等
+
+<DesignToken componentName='global' reg={/color-disabled/}/>
+
+### 常量色 - static
+
+界面中不跟随主题及明暗模式切换的颜色
+
+<DesignToken componentName='global' reg={/((--semi-black)|(--semi-white))$/}/>
+
+### 拟阴影色 - shadow
+
+浅阴影,通过 border 模拟的扁平阴影效果,主要用在 Table 组件
+
+<DesignToken componentName='global' reg={/^--semi-color-shadow$/}/>
+
+## 字体排版
+
+字体排版用来传达信息内容,并界面看起来有秩序
+
+### 字号
+
+决定不同层级文本的大小
+
+<DesignToken componentName='global' reg={/font-size/}/>
+
+### 字重
+
+决定不同层级文本的粗细
+
+<DesignToken componentName='global' reg={/font-weight/}/>
+
+### 字体
+
+应用中各级文本使用的字体,为减少打包体积,默认英文字体 Inter 需要单独引入
+
+业务侧如果想使用,需要在你的css中增加font-face声明(不自带在Semi中,是由于该字体略大,默认加载可能会影响业务首屏速度),由业务自行决定是否需要使用
+
+```css
+@font-face {
+  font-family: "Inter";
+  src: url("https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/slepweh7nupqpognuhbo/Inter-Regular.ttf") format("ttf"),
+}
+
+@font-face {
+  font-family: "Inter-Bold";
+  src: url("https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/slepweh7nupqpognuhbo/Inter-Bold.ttf") format("ttf"),
+}
+
+```
+
+<DesignToken componentName='global' reg={/font-family/}/>
+
+## 圆角
+
+使用圆角来描述容器与界面元素的轮廓,从一定程度决定产品的视觉调性
+
+<DesignToken componentName='global' reg={/border-radius/}/>
+
+## 阴影
+
+阴影通常用来表达界面元素的层级,阴影越重的元素距离用户越近
+
+<DesignToken componentName='global' reg={/\$shadow/}/>
+
+## 尺寸
+
+尺寸变量被应用在各个组件及内部元素中,用来调整控件的大小、描边的粗细、图标的尺寸等
+
+### 高度
+
+<DesignToken componentName='global' reg={/\height-control/}/>
+
+### 描边尺寸
+
+<DesignToken componentName='global' reg={/\$border-thickness/}/>
+
+### 图标尺寸
+
+<DesignToken componentName='global' reg={/\$width-icon/}/>
+
+## 间距
+
+间距变量被应用在各个组件内部,或组件与组件之间,用来调整产品整体的密集和紧凑程度
+
+<DesignToken componentName='global' reg={/(spacing-)|(width-base)|(loose)/}/>
+
+## z-index
+
+用来描述界面元素的前后顺序关系
+
+<DesignToken componentName='global' reg={/z-/}/>
+
+## 尚未支持的变量
+目前,Semi 尚未支持以下类别的全局变量,如果你有相关需求,可以通过issue进行反馈,详细描述你的预期需求,我们会在评估后进行处理
+
+**段落行高 line height**
+
+**字间距 letter spacing**
+
+**时长 duration**
+
+**媒体查询 media query**
+
+## 定制
+
+如果你需要定制全局变量样式,请前往 [Semi DSM](https://semi.design/dsm) ,制作你自己的主题并发布

+ 392 - 0
content/basic/typography/index-en-US.md

@@ -0,0 +1,392 @@
+---
+localeCode: en-US
+order: 14
+category: Basic
+title:  Typography
+subTitle: Typography
+icon: doc-typography
+brief: The basic format of text, images, and paragraphs.
+---
+
+
+## When to Use
+
+-   To display the text content of articles, blogs, logs, etc.
+-   To take basic operations such as copying and omitting text.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Typography } from '@douyinfe/semi-ui';
+```
+### Title
+
+Use `heading` to set different levels of headint title.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Title } = Typography;
+  return (
+    <div>
+        <Title  style={{margin: '8px 0'}} >h1. Semi Design</Title>
+        <Title with={2} style={{margin: '8px 0'}} >h2. Semi Design</Title>
+        <Title heading={3} style={{margin: '8px 0'}} >h3. Semi Design</Title>
+        <Title heading={4} style={{margin: '8px 0'}} >h4. Semi Design</Title>
+        <Title heading={5} style={{margin: '8px 0'}} >h5. Semi Design</Title>
+        <Title heading={6} style={{margin: '8px 0'}} >h6. Semi Design</Title>
+    </div>
+  );
+}
+```
+
+### Text
+
+Text component has different built-in styles. You could also pass `icon` to use the build-in styles for icon. Different from passing icon to children, using `icon` for link will have no underline in compliance with Semi design principles.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+        <Text>Text</Text>
+        <br />
+        <br />
+        <Text type="secondary">Secondary</Text>
+        <br />
+        <br />
+        <Text type="tertiary">Tertiary v>=1.2.0</Text>
+        <br />
+        <br />
+        <Text type="quaternary">Quaternary v>=1.2.0</Text>
+        <br />
+        <br />
+        <Text type="warning">Warning</Text>
+        <br />
+        <br />
+        <Text type="success">Success v>=1.7.0</Text>
+        <br />
+        <br />
+        <Text type="danger">Danger</Text>
+        <br />
+        <br />
+        <Text disabled>Disabled</Text>
+        <br />
+        <br />
+        <Text mark>Default Mark</Text>
+        <br />
+        <br />
+        <Text code>Example Code</Text>
+        <br />
+        <br />
+        <Text underline>Underline</Text>
+        <br />
+        <br />
+        <Text delete>Deleted</Text>
+        <br />
+        <br />
+        <Text strong>Strong</Text>
+    </div>
+  );
+}
+```
+
+You could pass object to `link`, which will be mounted on `<a>`.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+import { IconLink } from '@douyinfe/semi-icons';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+      <Text link={{ href: 'https://semi.design/' }}>Link</Text>
+      <br />
+      <br />
+      <Text link={{ href: 'https://semi.design/' }}>Open Website</Text>
+      <br />
+      <br />
+      <Text link icon={<IconLink />} underline>Link</Text>
+    </div>
+  )
+}
+```
+
+### Paragraph
+
+Paragraph component has two spacings. You could set`spacing='extended'` for a looser spacing.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Title } = Typography;
+  return (
+    <div>
+        <Title heading={5}>Default Spacing</Title>
+        <Paragraph>
+            Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+        <br />
+        <Title heading={5}>Extended Spacing</Title>
+        <Paragraph spacing="extended">
+            Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+### Size
+
+Paragraph and Text component support two sizes, `small`(12px) and `normal`(14px). By default it is set to `normal`。
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Text } = Typography;
+  return (
+    <div>
+        <Text>Normal</Text>
+        <Paragraph spacing="extended">
+            Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+        <br />
+        <Text size='small'>Small</Text>
+        <Paragraph size='small'>
+            Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+### Interactive
+
+Copyable text.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Text } = Typography;
+
+  return (
+    <div>
+        <Paragraph copyable>Click the right icon to copy text.</Paragraph>
+        <Paragraph copyable={{ content: 'Hello, Semi Design!' }}>Click to copy text.</Paragraph>
+        <Paragraph copyable={{ onCopy: () => Toast.success({ content: 'Successfully copied.'}) }}>Click the right icon to copy.</Paragraph>
+        <br/>
+        <Text type="secondary">Paste here: </Text>
+        <br/>
+        <TextArea autosize style={{width: 320, marginTop: 4}} rows={3} />
+    </div>
+  );
+}
+```
+
+### Ellipsis
+
+Show ellipsis if text is overflowed. Refer to [Ellipsis Config](#Ellipsis-Config) for detailed configuration.
+> At this moment, only pure text truncation is supported.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Text, Title } = Typography;
+
+  return (
+    <div>
+        <Title heading={5} ellipsis={{ showTooltip: true }} style={{ width: 250 }}>
+            This is a supercalifragilisticexpialidocious title
+        </Title>
+        <br />
+        <Text 
+          ellipsis={{ 
+            showTooltip:{
+              opts: { content: 'This is a supercalifragilisticexpialidocious tooltip' }
+            }
+          }}
+          style={{ width: 150 }}
+        >
+          Custom tooltip text if you need
+        </Text>
+        <br />
+        <Text link ellipsis={{ showTooltip: true, pos: 'middle' }} style={{ width: 150 }}>
+            This is a supercalifragilisticexpialidocious link
+        </Text>
+        <br/>
+        <Paragraph ellipsis={{ suffix: '-Macbeth' }} style={{ width: 300 }}>
+            With suffix: Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3 }} style={{ width: 300 }}>
+            Multi-line ellipsis: Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3, showTooltip: {type: 'popover', opts: {style: {width: 300}}} }} style={{ width: 300 }}>
+            With Popover: Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3, expandable: true, collapsible: true, collapseText: 'Show Less', onExpand: (bool, e) => console.log(bool, e) }} style={{ width: 300 }}>
+            Expandable and collapsible: Life's but a walking shadow, a poor player, that struts and frets his hour upon the stage, and then is heard no more; it is a tale told by an idiot, full of sound and fury, signifying nothing.
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+<Notice type="primary" title="Tips">
+    <div>When the tooltip does not wrap in the pop-up tooltip when the long text occurs, please set it manually <a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/word-break" target="_blank"  rel="noopener noreferrer">word-break</a>. The reason why we did not have built-in content is that different language content (pure English, Chinese, mixed Chinese and English) have different requirements for word-break, so the component layer does not make this preset.</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+
+  return (
+    <div>
+      <Text 
+        ellipsis={{ 
+          showTooltip:{
+            opts: { content: 'Insfrastructure|Data-inf|bytegraph.cheetah.user_relation' }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        Customized configuration can be made on demand when long text is truncated
+      </Text>
+      <br />
+      <Text 
+        ellipsis={{ 
+          showTooltip:{
+            opts: { content: 'Insfrastructure|Data-inf|bytegraph.cheetah.user_relation', className: 'components-typography-demo' }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        Customized configuration can be made on demand when long text is truncated
+      </Text>
+      <br />
+      <Text 
+        ellipsis={{
+          showTooltip:{
+            opts: { content: 'Insfrastructure|Data-inf|bytegraph.cheetah.user_relation', style: { wordBreak: 'break-all' } }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        Customized configuration can be made on demand when long text is truncated
+      </Text>
+    </div>
+  );
+}
+```
+
+```scss
+// config word-break
+
+.components-typography-demo {
+    word-break: break-word;
+    // or
+    word-break: break-all;
+}
+```
+
+## API Reference
+
+### Typography.Text
+
+| Properties | Instructions                                                                                                                             | type                                                  | Default   | version |
+| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | --------- | ------- |
+| copyable   | Toggle whether to be copyable                                                                                                            | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0  |
+| code       | wrap with `code` element                                                                                                                 | boolean                                               | -         |         |
+| component  | Custom rendering html element                                                                                                            | html element                                          | span      |         |
+| delete     | Deleted style                                                                                                                            | boolean                                               | false     | 0.27.0  |
+| disabled   | Disabled style                                                                                                                           | boolean                                               | false     | 0.27.0  |
+| ellipsis   | Display ellipsis when text overflows                                                                                                     | boolean\|object:Ellipsis Config                       | false     | 0.34.0  |
+| icon       | Prefix icon.                                                                                                                             | ReactNode                                             | -         | 0.27.0  |
+| link       | Toggle whether to display as a link. When passing object, the attributes will be transparently passed to the a tag                       | boolean\|object                                       | false     | 0.27.0  |
+| mark       | Marked style                                                                                                                             | boolean                                               | false     | 0.27.0  |
+| size       | Size, one of `normal`,`small`                                                                                                           | string                                                | `normal`  | 0.27.0  |
+| strong     | Bold style                                                                                                                               | boolean                                               | false     | 0.27.0  |
+| type       | Type, one of `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**) , `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                                                | `primary` | 0.27.0  |
+| underline  | Underlined style                                                                                                                         | boolean                                               | false     | 0.27.0  |
+
+### Typography.Title
+
+| Properties | Instructions                                                                                                                            | type                                                  | Default   | version |
+| ---------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | --------- | ------- |
+| copyable   | Toggle whether to be copyable                                                                                                           | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0  |
+| component  | Custom rendering html element. The default is determined by heading prop                                                                | html element                                          | h1~h6     |         |
+| delete     | Deleted style                                                                                                                           | boolean                                               | false     | 0.27.0  |
+| disabled   | Disabled style                                                                                                                          | boolean                                               | false     | 0.27.0  |
+| ellipsis   | Display ellipsis when text overflows                                                                                                    | boolean\|object:Ellipsis Config                       | false     | 0.34.0  |
+| heading    | Heading level, one of 1, 2, 3,4,5,6                                                                                                | number                                                | 1         | 0.27.0  |
+| link       | Toggle whether to display as a link. When passing object, the attributes will be transparently passed to the a tag                      | boolean\|object                                       | false     | 0.27.0  |
+| mark       | Marked style                                                                                                                            | boolean                                               | false     | 0.27.0  |
+| type       | Type, one of `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**), `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                                                | `primary` | 0.27.0  |
+| underline  | Underlined style                                                                                                                        | boolean                                               | false     | 0.27.0  |
+
+### Typography.Paragraph
+
+| Properties | Instructions                                                                                                                            | type                                                  | Default   | version |
+| ---------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | --------- | ------- |
+| copyable   | Toggle whether to be copyable                                                                                                           | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0  |
+| component  | Custom rendering html element                                                                                                           | html element                                          | p         |         |
+| delete     | Deleted style                                                                                                                           | boolean                                               | false     | 0.27.0  |
+| disabled   | Disabled style                                                                                                                          | boolean                                               | false     | 0.27.0  |
+| ellipsis   | Display ellipsis when text overflows                                                                                                    | boolean\|object:Ellipsis Config                       | false     | 0.34.0  |
+| link       | Toggle whether to display as a link. When passing object, the attributes will be transparently passed to the a tag                      | boolean\|object                                       | false     | 0.27.0  |
+| mark       | Marked style                                                                                                                            | boolean                                               | false     | 0.27.0  |
+| size       | Size, one of `normal`,`small`                                                                                                          | string                                                | `normal`  | 0.27.0  |
+| spacing    | paragraph spacing, one of `normal`, `extended`                                                                                          | string                                                | `normal`  | 0.27.0  |
+| strong     | Bold style                                                                                                                              | boolean                                               | false     | 0.27.0  |
+| type       | Type, one of `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**), `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                                                | `primary` | 0.27.0  |
+| underline  | Underlined style                                                                                                                        | boolean                                               | false     | 0.27.0  |
+
+
+### Ellipsis Config
+**v >= 0.34.0**
+
+| Properties   | Instructions                                                                                                                                                                                 | type                                                | Default    |
+| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ---------- |
+| collapseText | Displayed text to collapse                                                                                                                                                                   | string                                              | `Collapse` |
+| collapsible  | Toggle whether text is collapsible                                                                                                                                                           | boolean                                             | false      |
+| expandText   | Displayed text to expand                                                                                                                                                                     | string                                              | `Expand`   |
+| expandable   | Toggle whether text is expandable                                                                                                                                                            | boolean                                             | false      |
+| pos          | Position to start ellipsis, one of `end`, `middle`                                                                                                                                           | string                                              | `end`      |
+| rows         | Number of rows that should not be truncated                                                                                                                                                  | number                                              | 1          |
+| showTooltip  | Toggle whether to show tooltip, if passed in as object: type,type of component to show tooltip, one of `Tooltip`, `Popover`; opts, properties that will be passed directly to the component | boolean\|{type: 'tooltip'\|'popover', opts: object} | false      |
+| suffix       | Text suffix that will not be truncated                                                                                                                                                       | string                                              | -          |
+| onExpand     | Callback when expand or collapse                                                                                                                                                             | function(expanded: bool, Event: e)                  | -          |
+
+
+### Copyable Config
+| Properties | Instructions                            | Type                                           | Default | Version |
+| ---------- | --------------------------------------- | ---------------------------------------------- | ------- | ------- |
+| content    | Copied content                          | string                                         | -       | 0.27.0  |
+| copyTip    | Tooltip content when hovering over icon | React.node                                     | -       | 1.0.0   |
+| successTip | Successful tip content                  | React.node                                     | -       | 0.33.0  |
+| onCopy     | Callback for copy action                | Function(e:Event, content:string, res:boolean) | -       | 0.27.0  |
+
+## Design Tokens
+<DesignToken/>

+ 376 - 0
content/basic/typography/index.md

@@ -0,0 +1,376 @@
+---
+localeCode: zh-CN
+order: 14
+category: 基础
+title:  Typography 版式
+icon: doc-typography
+brief: 文字,图片,段落的基本格式。
+---
+
+## 使用场景
+- 对文章、博客、日志等的文本内容进行展示时。
+- 对文本进行复制和省略等基础操作时。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Typography } from '@douyinfe/semi-ui';
+```
+### 标题组件
+通过设置 heading 可以展示不同级别的标题。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Title } = Typography;
+  return (
+    <div>
+        <Title  style={{margin: '8px 0'}} >h1. Semi Design</Title>
+        <Title heading={2} style={{margin: '8px 0'}} >h2. Semi Design</Title>
+        <Title heading={3} style={{margin: '8px 0'}} >h3. Semi Design</Title>
+        <Title heading={4} style={{margin: '8px 0'}} >h4. Semi Design</Title>
+        <Title heading={5} style={{margin: '8px 0'}} >h5. Semi Design</Title>
+        <Title heading={6} style={{margin: '8px 0'}} >h6. Semi Design</Title>
+    </div>
+  );
+}
+```
+
+### 文本组件
+内置不同样式的文本。可以通过 `icon` 属性传入图标,这种方式传入的图标默认与文本有间距,同时在链接文本的情况不会出现下划线符合设计规范。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+        <Text>Text</Text>
+        <br />
+        <br />
+        <Text type="secondary">Secondary</Text>
+        <br />
+        <br />
+        <Text type="tertiary">Tertiary v>=1.2.0</Text>
+        <br />
+        <br />
+        <Text type="quaternary">Quaternary v>=1.2.0</Text>
+        <br />
+        <br />
+        <Text type="warning">Warning</Text>
+        <br />
+        <br />
+        <Text type="danger">Danger</Text>
+        <br />
+        <br />
+        <Text type="success">Success v>=1.7.0</Text>
+        <br />
+        <br />
+        <Text disabled>Disabled</Text>
+        <br />
+        <br />
+        <Text mark>Default Mark</Text>
+        <br />
+        <br />
+        <Text code>Example Code</Text>
+        <br />
+        <br />
+        <Text underline>Underline</Text>
+        <br />
+        <br />
+        <Text delete>Deleted</Text>
+        <br />
+        <br />
+        <Text strong>Strong</Text>
+    </div>
+  );
+}
+```
+链接文本支持传入 `object`,将对应的属性挂在 `<a>` 标签上。  
+**v>=1.0** 后默认不再有下划线,可以配合 underline 属性在 hover,active 态增加下划线的样式。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+import { IconLink } from '@douyinfe/semi-icons';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+      <Text link={{ href: 'https://semi.design/' }}>链接文本</Text>
+      <br />
+      <br />
+      <Text link={{ href: 'https://semi.design/' }}>打开网站</Text>
+      <br />
+      <br />
+      <Text link icon={<IconLink />} underline>带下划线的网页链接</Text>
+    </div>
+  )
+}
+```
+
+### 段落组件
+段落组件拥有两种行距,可以通过设置 `spacing='extended'` 使用更宽松的行距。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Title } = Typography;
+  return (
+    <div>
+        <Title heading={5}>默认行距</Title>
+        <Paragraph>
+            Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+        <br />
+        <Title heading={5}>宽松行距</Title>
+        <Paragraph spacing="extended">
+            Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+### 文本大小
+段落组件和文本组件支持两种尺寸,`small`(12px) 和 `normal`(14px),默认为`normal`。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Text } = Typography;
+  return (
+    <div>
+        <Text>正常文本</Text>
+        <Paragraph spacing="extended">
+            Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+        <br />
+        <Text size='small'>小文本</Text>
+        <Paragraph size='small'>
+            Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+### 可交互文本
+支持文本的复制。
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Text } = Typography;
+
+  return (
+    <div>
+        <Paragraph copyable>点击右边的图标复制文本。</Paragraph>
+        <Paragraph copyable={{ content: 'Hello, Semi Design!' }}>点击复制文本。</Paragraph>
+        <Paragraph copyable={{ onCopy: () => Toast.success({ content: '复制文本成功'}) }}>点击右边的图标复制文本。</Paragraph>
+        <br/>
+        <Text type="secondary">粘贴区域:</Text>
+        <br/>
+        <TextArea autosize style={{width: 320, marginTop: 4}} rows={3} />
+    </div>
+  );
+}
+```
+
+### 省略文本
+支持文本的省略,可以通过 `ellipsis` 配置相关参数,具体参考 [Ellipsis Config](#Ellipsis-Config)。
+
+> 目前只支持纯文本的截断
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Paragraph, Title, Text } = Typography;
+
+  return (
+    <div>
+        <Title heading={5} ellipsis={{ showTooltip: true }} style={{ width: 250 }}>
+            是一个很长很长很长很长5号标题
+        </Title>
+        <br />
+        <Text 
+          ellipsis={{ 
+            showTooltip:{
+              opts: { content: '这是自定义要展示的内容' }
+            }
+          }}
+          style={{ width: 150 }}
+        >
+          可以自定义浮层里的展示内容试试看吧
+        </Text>
+        <br/>
+        {/* link还可以传入object,如link={{ href: 'https://semi.design/zh-CN/basic/typography', target: '_blank' }} */}
+        <Text link ellipsis={{ showTooltip: true, pos: 'middle' }} style={{ width: 150 }}>
+            是一个很长很长很长很长的链接
+        </Text>
+        <br/>
+        <Paragraph ellipsis={{ suffix: '小尾巴' }} style={{ width: 300 }}>
+            有后缀的情况:Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3 }} style={{ width: 300 }}>
+            这是一个多行截断的例子:Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3, showTooltip: {type: 'popover', opts: {style: {width: 300}}} }} style={{ width: 300 }}>
+            多行截断,展示 Popover:Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+        <br/>
+        <Paragraph ellipsis={{ rows: 3, expandable: true, collapsible: true, collapseText: '折叠我吧', onExpand: (bool, e) => console.log(bool, e) }} style={{ width: 300 }}>
+            支持展开和折叠:Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
+        </Paragraph>
+    </div>
+  );
+}
+```
+
+<Notice type="primary" title="注意事项">
+    <div>当发生超长文本在弹出的 tooltip 没有换行时,请手动设置一下 <a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/word-break" target="_blank" rel="noopener noreferrer">word-break</a>。我们没有内置的原因是不同语言内容(纯英文、中文、中英文混合)对 word-break 的需求不太一致,所以组件层没有做这个预设。</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+
+  return (
+    <div>
+      <Text 
+        ellipsis={{ 
+          showTooltip:{
+            opts: { content: '架构|Data-inf|bytegraph.cheetah.user_relation' }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        有问题的超长文本发生截断时可按需进行自定义配置
+      </Text>
+      <br />
+      <Text 
+        ellipsis={{ 
+          showTooltip:{
+            opts: { content: '架构|Data-inf|bytegraph.cheetah.user_relation', className: 'components-typography-demo' }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        覆盖类名超长文本发生截断时可使用类名覆盖进行自定义配置
+      </Text>
+      <br />
+      <Text 
+        ellipsis={{
+          showTooltip:{
+            opts: { content: '架构|Data-inf|bytegraph.cheetah.user_relation', style: { wordBreak: 'break-all' } }
+          }
+        }}
+        style={{ width: 150 }}
+      >
+        覆盖style超长文本发生截断时可使用style进行自定义配置
+      </Text>
+    </div>
+  );
+}
+```
+
+```scss
+// 按需配置 word-break
+
+.components-typography-demo {
+    word-break: break-word;
+    // 或
+    word-break: break-all;
+}
+```
+
+## API参考
+
+### Typography.Text
+
+| 属性      | 说明                                                                                                                                      | 类型                              | 默认值    | 版本   |
+| --------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | --------- | ------ |
+| component | 自定义渲染元素                                                                                                                            | html element                      | span      |        |
+| code      | 是否被 `code` 元素包裹                                                                                                                            | boolean                      | -      |        |
+| copyable  | 是否可拷贝                                                                                                                                | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0 |
+| delete    | 添加删除线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+| disabled  | 禁用文本                                                                                                                                  | boolean                           | false     | 0.27.0 |
+| ellipsis  | 设置自动溢出省略                                                                                                                          | boolean\|object:Ellipsis Config   | false     | 0.34.0 |
+| icon      | 前缀图标                                                                                                                                  | ReactNode                         | -         | 0.27.0 |
+| link      | 是否为链接,传object时,属性将透传给a标签                                                                                                 | boolean\|object                   | false     | 0.27.0 |
+| mark      | 添加标记样式                                                                                                                              | boolean                           | false     | 0.27.0 |
+| size      | 文本大小,可选`normal`,`small`                                                                                                           | string                            | `normal`  | 0.27.0 |
+| strong    | 是否加粗                                                                                                                                  | boolean                           | false     | 0.27.0 |
+| type      | 文本类型,可选 `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**), `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                            | `primary` | 0.27.0 |
+| underline | 添加下划线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+
+### Typography.Title
+
+| 属性      | 说明                                                                                                                                      | 类型                              | 默认值    | 版本   |
+| --------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | --------- | ------ |
+| component | 自定义渲染元素,默认由 heading 决定                                                                                                       | html element                      | h1~h6     |        |
+| copyable  | 是否可拷贝                                                                                                                                | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0 |
+| delete    | 添加删除线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+| disabled  | 禁用文本                                                                                                                                  | boolean                           | false     | 0.27.0 |
+| ellipsis  | 设置自动溢出省略                                                                                                                          | boolean\|object:Ellipsis Config   | false     | 0.34.0 |
+| heading   | 标题级别,可选1, 2, 3,4,5,6,对应相应的标题                                                                                          | number                            | 1         | 0.27.0 |
+| link      | 是否为链接,传object时,属性将透传给a标签                                                                                                 | boolean\|object                   | false     | 0.27.0 |
+| mark      | 添加标记样式                                                                                                                              | boolean                           | false     | 0.27.0 |
+| type      | 文本类型,可选 `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**), `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                            | `primary` | 0.27.0 |
+| underline | 添加下划线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+
+### Typography.Paragraph
+| 属性      | 说明                                                                                                                                      | 类型                              | 默认值    | 版本   |
+| --------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | --------- | ------ |
+| component | 自定义渲染元素                                                                                                                            | html element                      | p         |        |
+| copyable  | 是否可拷贝                                                                                                                                | boolean \| object:[Copyable Config](#Copyable-Config) | false     | 0.27.0 |
+| delete    | 添加删除线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+| disabled  | 禁用文本                                                                                                                                  | boolean                           | false     | 0.27.0 |
+| ellipsis  | 设置自动溢出省略                                                                                                                          | boolean\|object:Ellipsis Config   | false     | 0.34.0 |
+| link      | 是否为链接,传object时,属性将透传给a标签                                                                                                 | boolean\|object                   | false     | 0.27.0 |
+| mark      | 添加标记样式                                                                                                                              | boolean                           | false     | 0.27.0 |
+| size      | 文本大小,可选`normal`,`small`                                                                                                           | string                            | `normal`  | 0.27.0 |
+| spacing   | 行距大小,可选`normal`,`extended`                                                                                                           | string                            | `normal`  | 0.27.0 |
+| strong    | 是否加粗                                                                                                                                  | boolean                           | false     | 0.27.0 |
+| type      | 文本类型,可选 `primary`, `secondary`, `warning`, `danger`, `tertiary`(**v>=1.2.0**), `quaternary`(**v>=1.2.0**), `success`(**v>=1.7.0**) | string                            | `primary` | 0.27.0 |
+| underline | 添加下划线样式                                                                                                                            | boolean                           | false     | 0.27.0 |
+
+### Ellipsis Config
+**v >= 0.34.0**
+
+| 属性         | 说明                                                                                                              | 类型                                                | 默认值 |
+| ------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ------ |
+| collapseText | 折叠的展示文本                                                                                                    | string                                              | `收起` |
+| collapsible  | 是否支持折叠                                                                                                      | boolean                                             | false  |
+| expandText   | 展开的展示文本                                                                                                    | string                                              | `展开` |
+| expandable   | 是否支持展开                                                                                                      | boolean                                             | false  |
+| pos          | 省略截断的位置,支持末尾和中间截断:`end`, `middle`                                                               | string                                              | `end`  |
+| rows         | 省略溢出行数                                                                                                      | number                                              | 1      |
+| showTooltip  | 是否展示 tooltip 及相关配置: type,浮层内容承载的组件,支持 Tooltip\| Popover;opts,其他需要透传给浮层组件的属性 | boolean\|{type: 'tooltip'\|'popover', opts: object} | false  |
+| suffix       | 始终展示的后缀                                                                                                    | string                                              | -      |
+| onExpand     | 展开/收起的回调                                                                                                   | function(expanded: bool, Event: e)                  | -      |
+
+### Copyable Config
+| 属性       | 说明                        | 类型                                           | 默认值 | 版本   |
+| ---------- | --------------------------- | ---------------------------------------------- | ------ | ------ |
+| content    | 复制出的文本                | string                                         | -      | 0.27.0 |
+| copyTip    | 复制图标的 tooltip 展示内容 | React.node                                     | -      | 1.0.0  |
+| successTip | 复制成功的展示内容          | React.node                                     | -      | 0.33.0 |
+| onCopy     | 复制回调                    | Function(e:Event, content:string, res:boolean) | -      | 0.27.0 |
+
+## 设计变量
+<DesignToken/>

+ 188 - 0
content/feedback/banner/index-en-US.md

@@ -0,0 +1,188 @@
+---
+localeCode: en-US
+order: 60
+category: Feedback
+title:  Banner
+subTitle: Banner
+icon: doc-banner
+dir: column
+brief: The Banner component is usually used to identify the status or notification of the full page. It is usually resident and requires the user to close it initiatively.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Banner } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Banner, Layout, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const [visible, setVisible] = useState(false);
+    const changeVisible = () => {
+      setVisible(!visible);
+    };
+    const { Header, Footer, Content } = Layout;
+    const banner = (
+      <Banner 
+          onClose={changeVisible}
+          description="A pre-released version is available"
+      />
+    );
+    return (
+        <>
+          <Layout className='components-layout-demo banner-basic'>
+              <Header>Header</Header>
+              {visible? banner : null}
+              <Content>Content</Content>
+              <Footer>Footer</Footer>
+          </Layout>
+          <Button
+            onClick={changeVisible}
+            style={{
+              display: 'block',
+              width: '120px',
+              margin: '0 auto'
+            }}
+          >
+            Show Banner
+          </Button>
+        </>
+      );
+}
+```
+
+### Types
+
+The `type` prop supports one of: `default`(default),`danger`,`warning`, `success`.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Banner 
+      type="info"
+      description="A pre-released version is available."
+    />
+    <br/>
+    <Banner 
+      type="warning"
+      description="This version of the document is going to expire after 4 days."
+    />
+    <br/>
+    <Banner 
+      type="danger"
+      description="This document was deprecated since Jan 1, 2019."
+    />
+    <br/>
+    <Banner 
+      type="success"
+      description="You are viewing the latest version of this document."
+    />
+  </>
+)
+```
+
+
+### Use in Container
+You could set  `fullMode={false}` to use style for non-fullscreen mode。
+Also, use `bordered` for bordered style.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner, Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+  
+  return (
+    <div style={{width: 640 }} className="components-banner-demo">
+      <Banner fullMode={false} type="info" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>Don't know AppKey?</div>}
+        description={<div>You can contact the corresponding R & D students to confirm whether you have applied for an application on <Text link={{ href: 'https://semi.design/' }}>the application cloud platform</Text> , and fill in the corresponding information.</div>}
+      /><br/>
+      <Banner fullMode={false} type="warning" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>Don't know AppKey?</div>}
+        description={<div>You can contact the corresponding R & D students to confirm whether you have applied for an application on <Text link={{ href: 'https://semi.design/' }}>the application cloud platform</Text> , and fill in the corresponding information.</div>}
+      /><br/>
+      <Banner fullMode={false} type="danger" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>Don't know AppKey?</div>}
+        description={<div>You can contact the corresponding R & D students to confirm whether you have applied for an application on <Text link={{ href: 'https://semi.design/' }}>the application cloud platform</Text> , and fill in the corresponding information.</div>}
+      /><br/>
+      <Banner fullMode={false} type="success" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>Don't know AppKey?</div>}
+        description={<div>You can contact the corresponding R & D students to confirm whether you have applied for an application on <Text link={{ href: 'https://semi.design/' }}>the application cloud platform</Text> , and fill in the corresponding information.</div>}
+      />
+    </div>
+  );
+}
+```
+
+```css
+.components-banner-demo {
+    .semi-banner-info.semi-banner-bordered {
+        border: 1px solid var(--semi-color-primary-disabled);
+    }
+    .semi-banner-warning.semi-banner-bordered {
+        border: 1px solid var(--semi-color-warning-light-active);
+    }
+    .semi-banner-danger.semi-banner-bordered {
+        border: 1px solid var(--semi-color-danger-light-active);
+    }
+    .semi-banner-success.semi-banner-bordered {
+        border: 1px solid var(--semi-color-success-light-active);
+    }
+}
+```
+
+### Customized Content
+Use `children` to create customized content.
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner } from '@douyinfe/semi-ui';
+
+() => (
+  <div style={{width: 500, padding: 20, border: '1px solid var(--semi-color-border)' }}>
+    <Banner
+      fullMode={false}
+      title="Title"
+      type="warning"
+      bordered
+      description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
+    >
+        <div className="semi-modal-footer">
+            <button className="semi-button semi-button-tertiary semi-button-light" type="button">No, thanks.</button>
+            <button className="semi-button semi-button-warning" type="button">Sounds great!</button>
+        </div>
+    </Banner>
+    <br/>
+  </div>
+)
+```
+
+## API Reference
+
+| Properties | Instructions                                                                             | Type     | Default               | Version | 
+| ---------- | ---------------------------------------------------------------------------------------- | -------- | --------------------- | --- |
+| bordered | Toggle if show border, only affects in non-fullscreen mode | boolean | false | 1.0 |
+| className | Classname | string | - |- |
+| closeIcon | Custom close icon,no icon if passed null | ReactNode | - | 1.0 |
+| description | Description texts | ReactNode | - | 1.0 |
+| fullMode| Toggle if banner is full screen | boolean | true | 1.0 |
+| icon | Custom icon, no icon if passed null | ReactNode | - | 1.0 |
+| onClose | Callback function when close banner | function | - |- |
+| style | Style | object | - |- |
+| title | Title | ReactNode | - | 1.0 |
+| type | Type of banner, one of `info`, `success`, `danger`, `warning` | string | `info` | - |
+
+## Design Tokens
+<DesignToken/>

+ 186 - 0
content/feedback/banner/index.md

@@ -0,0 +1,186 @@
+---
+localeCode: zh-CN
+order: 60
+category: 反馈类
+title:  Banner 通知横幅
+icon: doc-banner
+dir: column
+brief: 横幅通常用于标识全页的状态或通知等。它通常是常驻的,需要用户主动将其关闭。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Banner } from '@douyinfe/semi-ui';
+```
+### 基本用法
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Banner, Layout, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const [visible, setVisible] = useState(false);
+    const changeVisible = () => {
+      setVisible(!visible);
+    };
+    const { Header, Footer, Content } = Layout;
+    const banner = (
+      <Banner 
+          onClose={changeVisible}
+          description="A pre-released version is available"
+      />
+    );
+    return (
+        <>
+          <Layout className='components-layout-demo banner-basic'>
+              <Header>Header</Header>
+              {visible? banner : null}
+              <Content>Content</Content>
+              <Footer>Footer</Footer>
+          </Layout>
+          <Button
+            onClick={changeVisible}
+            style={{
+              display: 'block',
+              width: '120px',
+              margin: '0 auto'
+            }}
+          >
+            Show Banner
+          </Button>
+        </>
+      );
+}
+```
+
+### 不同类型
+
+支持4种类型:`info`、`warning`、`danger`、`success`。默认为 `info`。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Banner 
+      type="info"
+      description="A pre-released version is available."
+    />
+    <br/>
+    <Banner 
+      type="warning"
+      description="This version of the document is going to expire after 4 days."
+    />
+    <br/>
+    <Banner 
+      type="danger"
+      description="This document was deprecated since Jan 1, 2019."
+    />
+    <br/>
+    <Banner 
+      type="success"
+      description="You are viewing the latest version of this document."
+    />
+  </>
+)
+```
+
+
+### 非全屏模式
+可以设置  `fullMode={false}` 使用非全屏模式的 banner 样式。
+通过 `bordered` 属性可以设置边框。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner, Typography } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const { Text } = Typography;
+  
+  return (
+    <div style={{width: 640 }} className="components-banner-demo">
+      <Banner fullMode={false} type="info" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>不知道 AppKey?</div>}
+        description={<div>你可先联系对应的研发同学,确认是否已在 <Text link={{ href: 'https://semi.design/' }}>应用云平台</Text> 申请了应用,并填写对应的信息。</div>}
+      /><br/>
+      <Banner fullMode={false} type="warning" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>不知道 AppKey?</div>}
+        description={<div>你可先联系对应的研发同学,确认是否已在 <Text link={{ href: 'https://semi.design/' }}>应用云平台</Text> 申请了应用,并填写对应的信息。</div>}
+      /><br/>
+      <Banner fullMode={false} type="danger" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>不知道 AppKey?</div>}
+        description={<div>你可先联系对应的研发同学,确认是否已在 <Text link={{ href: 'https://semi.design/' }}>应用云平台</Text> 申请了应用,并填写对应的信息。</div>}
+      /><br/>
+      <Banner fullMode={false} type="success" bordered icon={null} closeIcon={null}
+        title={<div style={{fontWeight: 600, fontSize: '14px', lineHeight: '20px'}}>不知道 AppKey?</div>}
+        description={<div>你可先联系对应的研发同学,确认是否已在 <Text link={{ href: 'https://semi.design/' }}>应用云平台</Text> 申请了应用,并填写对应的信息。</div>}
+      />
+    </div>
+  );
+}
+```
+
+```
+.components-banner-demo {
+    .semi-banner-info.semi-banner-bordered {
+        border: 1px solid var(--semi-color-primary-disabled);
+    }
+    .semi-banner-warning.semi-banner-bordered {
+        border: 1px solid var(--semi-color-warning-light-active);
+    }
+    .semi-banner-danger.semi-banner-bordered {
+        border: 1px solid var(--semi-color-danger-light-active);
+    }
+    .semi-banner-success.semi-banner-bordered {
+        border: 1px solid var(--semi-color-success-light-active);
+    }
+}
+```
+
+### 自定义内容
+可以通过 children 自定义其他渲染内容。
+```jsx live=true dir="column"
+import React from 'react';
+import { Banner } from '@douyinfe/semi-ui';
+
+() => (
+  <div style={{width: 500, padding: 20, border: '1px solid var(--semi-color-border)' }}>
+    <Banner
+      fullMode={false}
+      title="Title"
+      type="warning"
+      bordered
+      description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
+    >
+        <div className="semi-modal-footer">
+            <button className="semi-button semi-button-tertiary semi-button-light" type="button">No, thanks.</button>
+            <button className="semi-button semi-button-warning" type="button">Sounds great!</button>
+        </div>
+    </Banner>
+    <br/>
+  </div>
+)
+```
+
+## API参考
+
+| 属性  | 说明        | 类型            | 默认值 | 版本 | 
+|-------|-------------|-----------------|--------| --- | 
+| bordered | 是否展示边框,仅在非全屏模式下有效 | boolean | false | 1.0 |
+| className | 类名 | string | - | - |
+| closeIcon | 自定义关闭icon,为 null 时不显示关闭按钮 | string\| ReactNode | - | 1.0 |
+| description | 描述内容 | ReactNode | - | 1.0 |
+| fullMode| 是否为全屏模式 | boolean | true | 1.0 |
+| icon | 自定义 icon,为 null 时不显示 icon | string\| ReactNode | - | 1.0 |
+| onClose | 关闭时的回调函数 | function | - | - |
+| style | 样式名 | object | - | - |
+| title | 标题 | ReactNode | - | 1.0 |
+| type | 类型,支持 `info`, `success`, `danger`, `warning` | string | `info` | - |
+
+## 设计变量
+<DesignToken/>

+ 320 - 0
content/feedback/notification/index-en-US.md

@@ -0,0 +1,320 @@
+---
+localeCode: en-US
+order: 61
+category: Feedback
+title:  Notification
+subTitle: Notification
+icon: doc-notification
+width: 65%
+brief: Notifications are used to actively send message notifications to users.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Notification } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+Close after 3 seconds.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => (
+  <Button
+    onClick={()=> Notification.open({
+      title: 'Hi, Bytedance',
+      content: 'ies dance dance dance',
+      with: 3
+    })}
+  >
+    Display Notification
+  </Button>
+)
+
+```
+
+### Position
+
+Use `position` to set pop up position, supporting one of: `top`、`bottom`、`topLeft`、`topRight`(default)、`bottomLeft`、`bottomRight`。
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button, ButtonGroup } from '@douyinfe/semi-ui';
+
+() => {
+  let opts = {
+    with: 3,
+    Position: 'topRight',
+    content: 'semi-ui-notification',
+    title: 'Hi bytedance',
+  };
+
+  return (
+    <>
+      <ButtonGroup>
+        <Button onClick={() => Notification.info({...opts, Position: 'top'})}>top</Button>
+        <Button onClick={() => Notification.info({...opts, position: 'topLeft'})}>topLeft</Button>
+        <Button onClick={() => Notification.info(opts)}>topRight</Button>
+      </ButtonGroup>
+      <br/><br/>
+      <ButtonGroup>
+        <Button onClick={() => Notification.info({...opts, position: 'bottom'})}>bottom</Button>
+        <Button onClick={() => Notification.info({...opts, position: 'bottomRight'})}>bottomRight</Button>
+        <Button onClick={() => Notification.info({...opts, position: 'bottomLeft'})}>bottomLeft</Button>
+      </ButtonGroup>
+    </>
+  )
+}
+```
+
+### With Icons
+
+Use different methods to show Notification with icons or you can pass in `icon` for customized icon.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+import { IconToutiaoLogo, IconVigoLogo } from '@douyinfe/semi-icons';
+
+() => {
+  let opts = {
+    title: 'Hi, Bytedance',
+    content: 'ies dance dance dance',
+    duration: 3,
+  };
+
+  return (
+    <>
+    <h5>Default Icon</h5>
+    <Button type='primary' onClick={()=>Notification.success(opts)} style={{margin: 4}}>
+      Success
+    </Button>
+    <Button onClick={() => Notification.info(opts)} style={{margin: 4}}>
+      Info
+    </Button>
+    <Button type="warning" onClick={()=>Notification.warning(opts)} style={{margin: 4}}>
+      Warning
+    </Button>
+    <Button type="danger" onClick={()=>Notification.error(opts)} style={{margin: 4}}>
+      Error
+    </Button>
+    <h5>Customized Icon</h5>
+    <Button
+      icon={<IconToutiaoLogo />}
+      style={{ marginRight: 5 }}
+      onClick={() =>
+          Notification.info({
+              ...opts,
+              icon: <IconToutiaoLogo style={{ color: 'red' }} />,
+          })
+      }
+    ></Button>
+    <Button
+      icon={<IconTiktokLogo />}
+      style={{ marginRight: 5 }}
+      onClick={() => Notification.info({ ...opts, icon: <IconTiktokLogo /> })}
+    ></Button>
+    <Button
+      icon={<IconVigoLogo />}
+      onClick={() => Notification.info({ ...opts, icon: <IconVigoLogo style={{ color: 'pink' }} />  })}
+    ></Button>
+    </>
+  )
+}
+```
+
+### Colored Background
+You could use `theme` for a colored background style. Default is `normal`.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+  let opts = {
+     title: 'Hi, Bytedance',
+    content: 'Hi, Bytedance dance dance',
+    duration: 3,
+    theme: 'light'
+  };
+
+  return (
+    <>
+    <Button onClick={() => Notification.info(opts)}>
+      Info
+    </Button>
+    <br/>
+    <br/>
+    <Button onClick={() => Notification.success(opts)}>
+      Success
+    </Button>
+    <br/>
+    <br/>
+    <Button type="warning" onClick={() => Notification.warning(opts)}>
+      Warning
+    </Button>
+    <br/>
+    <br/>
+    <Button type="danger" onClick={() => Notification.error(opts)}>
+      Error
+    </Button>
+    </>
+  )
+}
+```
+
+### Custom Children with Link
+
+Use with Typography to create operation links for more complicated situations.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button, Typography } from '@douyinfe/semi-ui';
+
+() => {
+  const { Text } = Typography;
+
+  let opts = {
+    title: 'This is a title',
+    content: (
+      <>
+       <div>Hi, Bytedance dance dance</div>
+        <div style={{marginTop: 8}}>
+          <Text link>More Info</Text>
+          <Text link style={{marginLeft: 20}}>Show Later</Text>
+        </div>
+      </>),
+    duration: 3,
+  };
+
+  return (
+    <Button
+      onClick={() => Notification.info(opts)}
+    >
+      Display Notification
+    </Button>
+  )
+}
+```
+
+### Delay
+
+Use `duration` to set up time delay. By default it closes after 3 seconds.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+  let opts = {
+    content: 'Hi, Bytedance dance dance',
+    duration: 10,
+  };
+
+  return (
+    <Button onClick={() => Notification.info(opts)}>
+      Close After 10s
+    </Button>
+  )
+}
+```
+
+### Manual Close
+
+Set `duration` to 0 if you do not want the Notification to close by itself. In this case, it could only be closed manually.
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+  let opts = {
+    content: 'Not auto close',
+    title: 'Hi',
+    duration: 0
+  };
+  const [id, setId] = useState([]);
+  function show() {
+    let id = Notification.info(opts);
+    setId(id);
+  }
+  function hide() {
+    Notification.close(id);
+  }
+  return (
+    <>
+      <Button type='primary' onClick={show}>
+        Show Notification
+      </Button>
+       <br/>
+       <br/>
+      <Button type='primary' onClick={hide}>
+        Hide Notification
+      </Button>
+    </>
+  )
+}
+```
+
+## API Reference
+
+The static methods provided are as follows:
+
+Display: You can pass in options object directly. Methods return the value of `id`: `const id = Notification.open({ /*...options*/ })`
+
+-   `Notification.open({content: 'message', duration: 3})`
+-   `Notification.info({content: 'message', duration: 3})`
+-   `Notification.error({content: 'message', duration: 3})`
+-   `Notification.warning({content: 'message', duration: 3})`
+-   `Notification.success({content: 'message', duration: 3})`
+
+Close Manually (`id` is the return value of the display methods)
+
+-   `Notification.close(id)`
+
+| Properties   | Instructions                                                                                   | type                 | Default    | version |
+| ------------ | ---------------------------------------------------------------------------------------------- | -------------------- | ---------- | ------- |
+| content      | Content                                                                                        | ReactNode | ''      |  |
+| duration     | Automatic close delay, no auto-close when set to 0                                             | number               | 3          |         |
+| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | () => HTMLElement | () => document.body    |  0.34.0     |
+| icon         | Topleft icon                                                                                   | ReactNode               |  |         |  |
+| position     | Pop-up position, one of `top`、`bottom`、`topLeft`、`topRight`、`bottomLeft`、`bottomRight`    | string               | `topRight` |         |
+| showClose    | Toggle Whether show close button                                                               | boolean              | true       | 0.25.0  |
+| theme | Style of background fill, one of `light`, `normal` | string | `normal`   |  1.0.0     |
+| title        | Title                                                                                          | string               | ReactNode | ''      |  |
+| zIndex       | Z-index value. Only take effect for the first time.                                                                               | number               | 1010       |         |
+| onClick      | Callback function when clicking the notification                                               | (e: event) => void   |            | 0.27 .0 |
+| onClose      | Callback function when closing notification, triggered for either auto-close or manually close | () => void |            |         |
+| onCloseClick | Callback function when actively clicking on the close button                                   | (id: string \| number) => void |            |         |
+
+The global configuration is set before any method call, and takes effect only once (>= 0.25.0):
+
+-   `Notification.config(config)`
+
+| Properties | Instructions                                                                                | type           | Default    | version |
+| ---------- | ------------------------------------------------------------------------------------------- | -------------- | ---------- | ------- |
+| bottom     | Bottom, absolute position                                                                   | number \| string | -          | 0.25.0  |
+| duration   | Automatic close delay, no auto-close when set to 0                                          | number(second) | 3          | 0.25.0  |
+| left       | Left, absolute position                                                                     | number \| string | -          | 0.25.0  |
+| position   | Pop-up position, one of `top`、`bottom`、`topLeft`、`topRight`、`bottomLeft`、`bottomRight` | string         | `topRight` | 0.25.0  |
+| right      | Right, absolute position                                                                    | number \| string | -          | 0.25.0  |
+| top        | Top, absolute position                                                                      | number \| string | -          | 0.25.0  |
+| zIndex     | Z-index                                                                                     | number         | 1010       | 0.25.0  |
+
+Globally Destroy (>= 0.25.0):
+
+-   `Notification.destroyAll()` ( >= 0.25.0 )
+
+Hook Notification ( >= 1.2.0 )
+-   `Notification.useNotification`
+
+When you need access Context, you could use ``Notification.useNotification` to create a `contextHolder` and insert to corresponding DOM tree. Notification created by hooks will be able to access the context where `contextHolder` is inserted. Hook Notification has following methods: `info`, `success`, `warning`, `error`, `open`, `close`. For more usage demo, refer to [useToast](/en-US/components/toast#useToast_Hooks)
+
+## Design Tokens
+<DesignToken/>

+ 312 - 0
content/feedback/notification/index.md

@@ -0,0 +1,312 @@
+---
+localeCode: zh-CN
+order: 61
+category: 反馈类
+title: Notification 通知
+icon: doc-notification
+width: 65%
+brief: 通知用于主动向用户发出消息通知
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Notification } from '@douyinfe/semi-ui';
+```
+
+### 普通通知
+
+最基本的用法,3s 后自动关闭
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Button
+        onClick={() =>
+            Notification.open({
+                title: 'Hi, Bytedance',
+                content: 'ies dance dance dance',
+                duration: 3,
+            })
+        }
+    >
+        Display Notification
+    </Button>
+);
+```
+
+### 不同位置弹出
+
+可以从多个不同位置弹出:默认右上角 `topRight`。可选值:`top`、`bottom`、`topLeft`、`topRight`、`bottomLeft`、`bottomRight`。
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button, ButtonGroup } from '@douyinfe/semi-ui';
+
+() => {
+    let opts = {
+        duration: 3,
+        position: 'topRight',
+        content: 'semi-ui-notification',
+        title: 'Hi bytedance',
+    };
+
+    return (
+        <>
+            <ButtonGroup>
+                <Button onClick={() => Notification.info({ ...opts, position: 'top' })}>top</Button>
+                <Button onClick={() => Notification.info({ ...opts, position: 'topLeft' })}>topLeft</Button>
+                <Button onClick={() => Notification.info(opts)}>topRight</Button>
+            </ButtonGroup>
+            <br />
+            <br />
+            <ButtonGroup>
+                <Button onClick={() => Notification.info({ ...opts, position: 'bottom' })}>bottom</Button>
+                <Button onClick={() => Notification.info({ ...opts, position: 'bottomRight' })}>bottomRight</Button>
+                <Button onClick={() => Notification.info({ ...opts, position: 'bottomLeft' })}>bottomLeft</Button>
+            </ButtonGroup>
+        </>
+    );
+};
+```
+
+### 带有图标的通知
+
+包括成功、失败、警告、提示
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+import { IconToutiaoLogo, IconVigoLogo } from '@douyinfe/semi-icons';
+
+() => {
+    let opts = {
+        title: 'Hi, Bytedance',
+        content: 'ies dance dance dance',
+        duration: 3,
+    };
+
+    return (
+        <>
+            <h5>默认的图标</h5>
+            <Button type="primary" onClick={() => Notification.success(opts)} style={{ margin: 4 }}>
+                Success
+            </Button>
+            <Button onClick={() => Notification.info(opts)} style={{ margin: 4 }}>
+                Info
+            </Button>
+            <Button type="warning" onClick={() => Notification.warning(opts)} style={{ margin: 4 }}>
+                Warning
+            </Button>
+            <Button type="danger" onClick={() => Notification.error(opts)} style={{ margin: 4 }}>
+                Error
+            </Button>
+            <h5>自定义图标</h5>
+            <Button
+                icon={<IconToutiaoLogo />}
+                style={{ marginRight: 5 }}
+                onClick={() =>
+                    Notification.info({
+                        ...opts,
+                        icon: <IconToutiaoLogo style={{ color: 'red' }} />,
+                    })
+                }
+            ></Button>
+            <Button
+                icon={<IconTiktokLogo />}
+                style={{ marginRight: 5 }}
+                onClick={() => Notification.info({ ...opts, icon: <IconTiktokLogo /> })}
+            ></Button>
+            <Button
+                icon={<IconVigoLogo />}
+                onClick={() => Notification.info({ ...opts, icon: <IconVigoLogo style={{ color: 'pink' }} />  })}
+            ></Button>
+        </>
+    );
+};
+```
+
+### 多色样式
+
+可以使用 `theme` 设置浅色填充样式提高与界面的对比,默认为 'normal' 的白色模式。
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+    let opts = {
+        title: 'Hi, Bytedance',
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+        theme: 'light',
+    };
+
+    return (
+        <>
+            <Button onClick={() => Notification.info(opts)}>Info</Button>
+            <br />
+            <br />
+            <Button onClick={() => Notification.success(opts)}>Success</Button>
+            <br />
+            <br />
+            <Button type="warning" onClick={() => Notification.warning(opts)}>
+                Warning
+            </Button>
+            <br />
+            <br />
+            <Button type="danger" onClick={() => Notification.error(opts)}>
+                Error
+            </Button>
+        </>
+    );
+};
+```
+
+### 链接文本
+
+配合 Typography 可以自定义操作区链接文本,用来配合更复杂的场景的使用。
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const { Text } = Typography;
+
+    let opts = {
+        title: 'This is a title',
+        content: (
+            <>
+                <div>Hi, Bytedance dance dance</div>
+                <div style={{ marginTop: 8 }}>
+                    <Text link>查看详情</Text>
+                    <Text link style={{ marginLeft: 20 }}>
+                        一会再看
+                    </Text>
+                </div>
+            </>
+        ),
+        duration: 3,
+    };
+
+    return <Button onClick={() => Notification.info(opts)}>Display Notification</Button>;
+};
+```
+
+### 修改延时
+
+自定义时长 10s,默认时长为 3s
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 10,
+    };
+
+    return <Button onClick={() => Notification.info(opts)}>Close After 10s</Button>;
+};
+```
+
+### 手动关闭
+
+设置 duration 为 0 时,通知将不会自动关闭,此时只能手动关闭。
+
+```jsx live=true
+import React from 'react';
+import { Notification, Button } from '@douyinfe/semi-ui';
+
+() => {
+    let opts = {
+        content: 'Not auto close',
+        title: 'Hi',
+        duration: 0,
+    };
+    const [id, setId] = useState([]);
+    function show() {
+        let id = Notification.info(opts);
+        setId(id);
+    }
+    function hide() {
+        Notification.close(id);
+    }
+    return (
+        <>
+            <Button type="primary" onClick={show}>
+                Show Notification
+            </Button>
+            <br />
+            <br />
+            <Button type="primary" onClick={hide}>
+                Hide Notification
+            </Button>
+        </>
+    );
+};
+```
+
+## API 参考
+
+组件提供的静态方法,使用方式如下:
+
+展示:可以直接传入 options 对象,返回值为`id`:`const id = Notification.open({ /*...options*/ })`
+
+-   `Notification.open({content: 'message', duration: 3})`
+-   `Notification.info({content: 'message', duration: 3})`
+-   `Notification.error({content: 'message', duration: 3})`
+-   `Notification.warning({content: 'message', duration: 3})`
+-   `Notification.success({content: 'message', duration: 3})`
+
+手动关闭 (id 为展示方法的返回值)
+
+-   `Notification.close(id)`
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| content | 通知内容 |ReactNode | '' |  |
+| duration | 自动关闭的延时,单位 s,设为 0 时不自动关闭 | number | 3 |  |
+| getPopupContainer | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative` | () => HTMLElement | () => document.body | 0.34.0 |
+| icon | 左上角 icon | React.Node |  |  |
+| position | 弹出位置,可选 `top`、`bottom`、`topLeft`、`topRight`、`bottomLeft`、`bottomRight` | string | `topRight` |  |
+| showClose | 是否展示关闭按钮 | boolean | true | 0.25.0 |
+| theme | 填充样式,支持`light`, `normal` | string | `normal` | 1.0.0 |
+| title | 通知标题 | ReactNode | '' |  |
+| zIndex | 弹层 z-index 值,首次设置一次生效 | number | 1010 |  |
+| onClick | 点击通知的回调函数 | (e: event) => void |  | 0.27.0 |
+| onClose | 通知关闭的回调函数(主动关闭、延时到达关闭都会触发) | () => void |  |  |
+| onCloseClick | 主动点击关闭按钮时的回调函数 | (id: string \| number) => void |  |  |
+
+全局配置在调用前提前配置,全局一次生效 ( >= 0.25.0 ):
+
+-   `Notification.config(config)`
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| bottom | 弹出位置 bottom | number \| string | - | 0.25.0 |
+| duration | 自动关闭的延时,单位 s,设为 0 时不自动关闭 | number | 3 | 0.25.0 |
+| left | 弹出位置 left | number \| string | - | 0.25.0 |
+| position | 弹出位置,可选 `top`、`bottom`、`topLeft`、`topRight`、`bottomLeft`、`bottomRight` | string | `topRight` | 0.25.0 |
+| right | 弹出位置 right | number \| string | - | 0.25.0 |
+| top | 弹出位置 top | number \| string | - | 0.25.0 |
+| zIndex | 弹层 z-index 值 | number | 1010 | 0.25.0 |
+
+## 设计变量
+
+<DesignToken/>
+
+全局销毁 ( >= 0.25.0 ):
+
+-   `Notification.destroyAll()` ( >= 0.25.0 )
+
+Hook Notification ( >= 1.2.0 ):
+
+-   `Notification.useNotification`  
+    当你需要使用 Context 时,可以通过 Notification.useNotification 创建一个 contextHolder 插入相应的节点中。此时通过 hooks 创建的 Notification 将会得到 contextHolder 所在位置的所有上下文。创建的 notification 对象拥有与以下方法:`info`, `success`, `warning`, `error`, `open`, `close`。使用方法可以参考:[useToast](/zh-CN/feedback/toast#Hooks用法)

+ 153 - 0
content/feedback/popconfirm/index-en-US.md

@@ -0,0 +1,153 @@
+---
+localeCode: en-US
+order: 62
+category: Feedback
+title:  Popconfirm
+subTitle: Popconfirm
+icon: doc-popconfirm
+brief: Click on the element to pop up the bubble confirmation box.
+---
+
+
+## When to Use
+
+When the operation of the target element requires further confirmation by the user, a floating layer prompt pops up near the target element to ask the user.
+
+and `Modal.confirm` Compared with the pop-up full-screen centered mode dialog box, the interactive form is lighter.
+
+## Demos
+
+
+### How to import
+
+```jsx import
+import { Popconfirm } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Popconfirm, Button, Toast } from '@douyinfe/semi-ui';
+
+() => {
+    const onConfirm = () => {
+      Toast.success('Confirm save!');
+    };
+
+    const onCancel = () => {
+      Toast.warning('Cancel save!');
+    }
+    return (
+      <Popconfirm
+          title="Are you sure you want to save this modification?"
+          content="This modification will be irreversible"
+          onConfirm={onConfirm}
+          onCancel={onCancel}
+      >
+          <Button>Save</Button>
+      </Popconfirm>
+    )
+}
+```
+
+### Type collocation
+
+Developers can use scenario-based `OK Type`/`Cancel Type`/`icon` Equal parameters are matched with different styles of bubble confirmation boxes.
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Popconfirm, Radio, RadioGroup, Button } from '@douyinfe/semi-ui/';
+import { IconAlertTriangle } from '@douyinfe/semi-icons';
+
+function TypesConfirmDemo(props = {}) {
+    const typeMap = {
+        default: {
+            icon: <IconAlertTriangle size="extra-large" />,
+        },
+        warning: {
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-warning)' }} size="extra-large" />,
+        },
+        danger: {
+            okType: 'danger',
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-danger)' }} size="extra-large" />,
+        },
+        tertiary: {
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-tertiary)' }} size="extra-large" />,
+        },
+    };
+
+    const keys = Object.keys(typeMap);
+    const [type, setType] = useState('default');
+    const [visible, _setVisible] = useState(true);
+
+    const changeType = e => {
+        const type = e && e.target && e.target.value;
+        if (type && keys.includes(type)) {
+            setType(type);
+        }
+    };
+
+    const setVisible = visible => _setVisible(visible);
+    const toggleVisible = () => setVisible(!visible);
+
+    return (
+        <div>
+            <RadioGroup onChange={changeType} value={type} style={{ marginTop: 14, marginBottom: 14 }}>
+                {keys.map(key => (
+                    <Radio key={key} value={key}>
+                        <strong style={{ color: `var(--semi-color-${key === 'default' ? 'primary' : key})` }}>{key}</strong>
+                    </Radio>
+                ))}
+            </RadioGroup>
+            <div>
+                <Popconfirm
+                    {...typeMap[type]}
+                    visible={visible}
+                    onVisibleChange={setVisible}
+                    trigger="custom"
+                    title="Are you sure to save this modification?"
+                    content="This modification will be irreversible"
+                >
+                    <Button onClick={toggleVisible}>Click here</Button>
+                </Popconfirm>
+            </div>
+        </div>
+    );
+}
+```
+
+### Use with Tooltip or Popover
+
+Please refer to [Use with Tooltip/Popover](/en-US/show/tooltip#Use-with-Popver-or-Popconfirm)
+
+## API Reference
+
+| Properties         | Instructions                                                                                                                                                          | Type                       | Default             | Version           |
+| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ------------------- | ----------------- |
+| arrowPointAtCenter | Whether the "small triangle" points to the center of the element, you need to pass in "showArrow = true" at the same time                                             | boolean                    | false               | **0.34.0** |
+| cancelText         | Cancel button text                                                                                                                                                    | string                     | "Cancel"            |
+| cancelButtonProps  | Properties for cancel button                                                                                                                                          | object                     |                     | **0.29.0**        |
+| cancelType         | Cancel button type                                                                                                                                                    | string                     | "tertiary"          |
+| content            | Content displayed                                                                                                                                                     | string \| ReactNode        |                     |
+| defaultVisible     | Bubble box is displayed by default                                                                                                                                    | boolean                    |                     | **0.19.0**        |
+| disabled           | Click on the Pop confirmation box to see if the bubbles pop up.                                                                                                       | boolean                    | false               |
+| getPopupContainer  | Specify the parent DOM, and the pop-up layer will be rendered into the DOM. Customization needs to set `position: relative`                                                                                                       | Function():HTMLElement           | () => document.body |
+| icon               | Custom pop bubble Icon icon                                                                                                                                           |  ReactNode        | <IconAlertTriangle size="extra-large" />    |
+| motion             | Whether there is animation when the drop-down list appears/hidden. You can customize animation by passing in an object that conforms to the structure | boolean\|object | true |
+| position           | Directions, optional values: `top`, `topLeft`, `topRight`, `leftTop`, `leftBottom`, `rightTop`, `rightTop`, `rightBottom`, `bottomLeft`, `bottomRight`, `bottomRight` | string                     | "bottomLeft"        |
+| okText             | Confirm button text                                                                                                                                | string                           | "Confirm"              |
+| okType             | Confirm button type                                                                                                                                | string                           | "primary"           |
+| okButtonProps      | Confirm button props                                                                                                                            | object                           |                     | **0.29.0**        |
+| showArrow          | Whether to show arrow triangle                                                                                                                         | boolean                          | false               |                   |
+| stopPropagation    | Whether to prevent the click event on the bomb layer from bubbling                                                                                                                | boolean                          | true                | **0.34.0** |
+| position           | Popup layer position,Optional value:`top`,`topLeft`,`topRight`,`left`,`leftTop`,`leftBottom`,<br/>`right`,`rightTop`,`rightBottom`,`bottom`,`bottomLeft`,`bottomRight` | string                           | "bottomLeft"        |
+| title              | Displayed title                                                                                                                                  | string\|ReactNode                |                     |
+| trigger            | Timing to trigger the display, optional value:hover / focus / click / custom                                                                                         | string                |   'click'                  |
+| visible            | Whether the bubble box displays controlled attributes                                                                                                                   | boolean                          |                     | **0.19.0**        |
+| zIndex             | Floating layer z-index value                                                                                                                                          | number                     | 1030                |
+| onConfirm          | Click the confirmation button to call back.                                                                                                                           | (e) => void                |                     |
+| onCancel           | Click the Cancel button to call back.                                                                                                                                 | (e) => void                |                     |
+| onVisibleChange    | Bubble box toggle shows hidden callbacks                                                                                                                              | (visible: boolean) => void | () => {}            | **0.19.0**        |
+
+## Design Tokens
+<DesignToken/>

+ 151 - 0
content/feedback/popconfirm/index.md

@@ -0,0 +1,151 @@
+---
+localeCode: zh-CN
+order: 62
+category: 反馈类
+title:  Popconfirm 气泡确认框
+icon: doc-popconfirm
+brief: 点击元素,弹出气泡式的确认框。
+---
+
+
+## 何时使用
+
+目标元素的操作需要用户进一步的确认时,在目标元素附近弹出浮层提示,询问用户。
+
+和 `Modal.confirm` 弹出的全屏居中模态对话框相比,交互形式更轻量。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Popconfirm } from '@douyinfe/semi-ui';
+```
+
+### 基本使用
+
+```jsx live=true
+import React from 'react';
+import { Popconfirm, Button, Toast } from '@douyinfe/semi-ui';
+
+() => {
+    const onConfirm = () => {
+      Toast.success('确认保存!');
+    };
+
+    const onCancel = () => {
+      Toast.warning('取消保存!');
+    }
+    return (
+      <Popconfirm
+          title="确定是否要保存此修改?"
+          content="此修改将不可逆"
+          onConfirm={onConfirm}
+          onCancel={onCancel}
+      >
+          <Button>保存</Button>
+      </Popconfirm>
+    )
+}
+```
+
+### 类型搭配
+
+开发者可以基于场景使用 `okType`/`cancelType`/`icon` 等参数搭配出不同风格的气泡式确认框。
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Popconfirm, Radio, RadioGroup, Button } from '@douyinfe/semi-ui';
+import { IconAlertTriangle } from '@douyinfe/semi-icons';
+
+function TypesConfirmDemo(props = {}) {
+    const typeMap = {
+        default: {
+            icon: <IconAlertTriangle size="extra-large" />,
+        },
+        warning: {
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-warning)' }} size="extra-large" />,
+        },
+        danger: {
+            okType: 'danger',
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-danger)' }} size="extra-large" />,
+        },
+        tertiary: {
+            icon: <IconAlertTriangle style={{ color: 'var(--semi-color-tertiary)' }} size="extra-large" />,
+        },
+    };
+
+    const keys = Object.keys(typeMap);
+    const [type, setType] = useState('default');
+    const [visible, _setVisible] = useState(true);
+
+    const changeType = e => {
+        const type = e && e.target && e.target.value;
+        if (type && keys.includes(type)) {
+            setType(type);
+        }
+    };
+
+    const setVisible = visible => _setVisible(visible);
+    const toggleVisible = () => setVisible(!visible);
+
+    return (
+        <div>
+            <RadioGroup onChange={changeType} value={type} style={{ marginTop: 14, marginBottom: 14 }}>
+                {keys.map(key => (
+                    <Radio key={key} value={key}>
+                        <strong style={{ color: `var(--semi-color-${key === 'default' ? 'primary' : key})` }}>{key}</strong>
+                    </Radio>
+                ))}
+            </RadioGroup>
+            <div>
+                <Popconfirm
+                    {...typeMap[type]}
+                    visible={visible}
+                    onVisibleChange={setVisible}
+                    trigger="custom"
+                    title="确定是否要保存此修改?"
+                    content="此修改将不可逆"
+                >
+                    <Button onClick={toggleVisible}>点击此处</Button>
+                </Popconfirm>
+            </div>
+        </div>
+    );
+}
+```
+
+### 搭配 Tooltip 或 Popover 使用
+
+请参考[搭配使用](/zh-CN/show/tooltip#%E6%90%AD%E9%85%8D-popover-%E6%88%96-popconfirm-%E4%BD%BF%E7%94%A8)
+
+## API 参考
+
+| 属性               | 说明                                                                                                                                        | 类型                             | 默认值              | 版本              |
+| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------- | ----------------- |
+| arrowPointAtCenter | “小三角”是否指向元素中心,需要同时传入"showArrow=true"                                                                                      | boolean                          | false               | **0.34.0** |
+| cancelText         | 取消按钮文字                                                                                                                                | string                           | "取消"              |
+| cancelButtonProps  | 取消按钮的 props                                                                                                                            | object                           |                     | **0.29.0**        |
+| cancelType         | 取消按钮类型                                                                                                                                | string                           | "tertiary"          |
+| content            | 显示的内容                                                                                                                                  | string\|ReactNode                |                     |
+| defaultVisible     | 气泡框默认是否展示                                                                                                                          | boolean                          |                     | **0.19.0**        |
+| disabled           | 点击 Popconfirm 子元素是否弹出气泡确认框                                                                                                    | boolean                          | false               |
+| getPopupContainer  | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义时容器需要设置 `position: relative`                                                                                                       | Function():HTMLElement           | () => document.body |
+| icon               | 自定义弹出气泡 Icon 图标                                                                                                                    | ReactNode                | <IconAlertTriangle size="extra-large" />    |
+| motion             | 下拉列表出现/隐藏时,是否有动画 | boolean\|object | true |
+| okText             | 确认按钮文字                                                                                                                                | string                           | "确认"              |
+| okType             | 确认按钮类型                                                                                                                                | string                           | "primary"           |
+| okButtonProps      | 确认按钮的 props                                                                                                                            | object                           |                     | **0.29.0**        |
+| position           | 方向,可选值:`top`,`topLeft`,`topRight`,`left`,`leftTop`,`leftBottom`,<br/>`right`,`rightTop`,`rightBottom`,`bottom`,`bottomLeft`,`bottomRight` | string                           | "bottomLeft"        |
+| showArrow          | 是否显示箭头三角形                                                                                                                          | boolean                          | false               |                   |
+| stopPropagation    | 是否阻止弹层上的点击事件冒泡                                                                                                                | boolean                          | true                | **0.34.0** |
+| title              | 显示的标题                                                                                                                                  | string\|ReactNode                |                     |
+| trigger            | 触发展示的时机,可选值:hover / focus / click / custom                                                                                         | string                |   'click'                  |
+| visible            | 气泡框是否展示的受控属性                                                                                                                    | boolean                          |                     | **0.19.0**        |
+| zIndex             | 浮层 z-index 值                                                                                                                             | number                           | 1030                |
+| onConfirm          | 点击确认按钮回调                                                                                                                            | Function(e)                      |                     |
+| onCancel           | 点击取消按钮回调                                                                                                                            | Function(e)                      |                     |
+| onVisibleChange    | 气泡框切换显示隐藏的回调                                                                                                               | Function(visible: boolean): void | () => {}            | **0.19.0**        |
+
+## 设计变量
+<DesignToken/>

+ 240 - 0
content/feedback/progress/index-en-US.md

@@ -0,0 +1,240 @@
+---
+localeCode: en-US
+order: 63
+category: Feedback
+title:  Progress
+subTitle: Progress
+icon: doc-progress
+width: 60%
+brief: Show the current progress of the operation.
+---
+
+
+## When to use
+
+Display the current progress and state of the operation for the user when the operation takes a long time to complete
+
+## Demos
+
+### How to import
+
+```jsx
+import { Progress } from '@douyinfe/semi-ui';
+```
+### Standard progress bar
+
+Use `stroke` Property to control the filling color of the progress bar  
+Use `Percent` Property to control completed progress  
+Use `size` Property control progress bar size  
+If the preset size is not satisfied, You can pass height to customize the height of the progress bar through `style` property.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 200 }}>
+        <Progress percent={10} stroke='#fc8800' />
+        <br/>
+        <Progress percent={25} stroke='#f93920' />
+        <br/>
+        <Progress percent={50} />
+        <br/>
+        <Progress percent={80} />
+        <br/>
+        <Progress percent={80} size='large' />
+        <br/>
+        <Progress percent={80} style={{ height: '8px' }}/>
+    </div>
+)
+```
+
+### Show percentage text
+
+You can control whether to show percentage number through the `showInfo` property
+In addition, you can format the percentage text show through `format`.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 200 }}>
+        <Progress percent={10} stroke='#fc8800' showInfo={true}/>
+        <br/>
+        <Progress percent={25} stroke='#f93920' showInfo={true}/>
+        <br/>
+        <Progress percent={50} showInfo={true}/>
+        <br/>
+        <Progress percent={50} showInfo={true} format={percent => (percent*10) + '‰'}/>
+    </div>
+)
+```
+
+### Vertical progress bar
+
+You can use vertical progress bar by setting `direction='vertical'`
+If perset width is not satisfied, you can pass width to customize the width of the vertical progress bar throught `style` property.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ height: 100, display: 'flex' }}>
+        <Progress percent={10} direction='vertical'/>
+        <Progress percent={25} direction='vertical' />
+        <Progress percent={50} direction='vertical' />
+        <Progress percent={80} direction='vertical' size='large' />
+        <Progress percent={80} direction='vertical' style={{ width: '8px' }}/>
+    </div>
+)
+```
+
+### Circular progress bar
+
+Set type to`circle`, the progress bar will be displayed in a ring shape. The default size of the progress bar is 72 x 72
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Progress percent={10} type='circle' style={{ margin: 5 }} />
+        <Progress percent={25} type='circle' style={{ margin: 5 }} />
+        <Progress percent={50} type='circle' style={{ margin: 5 }} />
+        <Progress percent={80} type='circle' style={{ margin: 5 }} />
+    </div>
+)
+```
+
+You can modify it's `width` to control the size of the circular progress bar.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <div>
+            <Progress percent={100} type='circle' width={100} style={{ margin: 5 }} />
+        </div>
+        <div>
+            <Progress percent={100} type='circle' width={100} style={{ margin: 5 }} stroke='#f93920' />
+        </div>
+    </React.Fragment>
+)
+```
+
+### Small circular progress bar
+
+Small progress bar default size is 24 x 24.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={10} type='circle' size='small' style={{ margin: 5 }} />
+        <Progress percent={25} type='circle' size='small' style={{ margin: 5 }} />
+        <Progress percent={50} type='circle' size='small' style={{ margin: 5 }} />
+        <Progress percent={80} type='circle' size='small' style={{ margin: 5 }} />
+    </React.Fragment>
+)
+```
+
+### Dynamic change percent
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
+
+() => {
+    const [percent, setPercent] = useState(40);
+    return (
+        <>
+            <div>
+                <Progress percent={percent} showInfo/>
+                <Button icon={<IconChevronLeft />} theme="light" onClick={()=> {setPercent(percent - 10)}} disabled={percent === 0} />
+                <Button icon={<IconChevronRight />} theme="light" onClick={()=> {setPercent(percent + 10)}} disabled={percent >=100 } />
+            </div>
+
+        </>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
+
+() => {
+    const [cirPerc, setCirPerc] = useState(40);
+    return (
+        <div>
+            <div><Progress percent={cirPerc} type='circle'/></div>
+            <Button icon={<IconChevronLeft />} theme="light" onClick={()=> {setCirPerc(cirPerc - 10)}} disabled={cirPerc === 0}/>
+            <Button icon={<IconChevronRight />} theme="light" onClick={()=> {setCirPerc(cirPerc + 10)}} disabled={cirPerc >=100 }/>
+        </div>
+    )
+}
+```
+
+### Custom central text content
+
+You can customize the central text by passing `format` function, and the argument of the format is the current percentage  
+If you don't need central text content, you can set `showInfo` to false or return an empty string directly in `format`
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={75} showInfo type='circle' format={(per) => per + 'Days'} style={{ margin:10 }}/>
+        <Progress percent={100} showInfo type='circle' format={(per) => 'Done'} style={{ margin:10 }}/>
+        <Progress percent={50} showInfo type='circle' showInfo={false} style={{ margin:10 }}/>
+    </React.Fragment>
+)
+```
+
+### Round / square edges
+
+With the `strokeLinecap` property, you can control the edge shape of the ring progress bar.
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={50} strokeLinecap='round' type='circle' style={{ margin: 10 }} />
+        <Progress percent={50} strokeLinecap='square' type='circle' style={{ margin:10 }} />
+    </React.Fragment>
+)
+```
+
+## API Reference
+
+| PROPERTIES | Instructions | Type | Default |
+|--- | --- | --- | --- |
+|className | style class name | string | |
+|direction | The direction of the bar progress bar `horizontal`, s`vertical` | string |'horizontal' |
+|format | Formatting function, the input parameter is the current percentage, the result of return will be directly rendered in the center of the circular progress bar | (percent: number) => ReactNode | (percent) => percent +'%' |
+|orbitStroke | Progress bar track fill color<br/>**provided after v1.0.0** | string |'var(--semi-color-fill-0)' |
+|percent | percentage of progress | number | |
+|showInfo | Whether to display the middle text in the circular progress bar, and whether to display the text on the right side of the bar-shaped progress bar | boolean | false |
+|size | size, optional `default`, `small` (only type=circle is effective), `large` (only type=line is effective) | string |'default' |
+|stroke | Fill color of progress bar | string |'var(--semi-color-success)' |
+|strokeLinecap | round corner `round`/square corner `square` (only effective in type='circle' mode) | string |'round' |
+|strokeWidth | When type is `line`, this property controls the height of the progress bar; when type is `circle`, this property controls the width of the progress bar | number | 4 |
+|style | style | CSSProperties | |
+|type | type, optional `line`, `circle` | string |'line' |
+|width | Width of circular progress bar | number | 72 when size='default', 24 for'small' |
+
+## Design Tokens
+<DesignToken/>

+ 269 - 0
content/feedback/progress/index.md

@@ -0,0 +1,269 @@
+---
+localeCode: zh-CN
+order: 63
+category: 反馈类
+title: Progress 进度条
+icon: doc-progress
+width: 60%
+brief: 展示操作的当前进度。
+---
+
+## 何时使用
+
+在操作需要较长时间才能完成时,为用户显示该操作的当前进度和状态
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Progress } from '@douyinfe/semi-ui';
+```
+
+### 标准的进度条
+
+通过`stroke`属性来控制进度条的填充色  
+通过`percent`属性控制已完成的进度  
+通过`size`属性控制进度条尺寸  
+如果`size`预设的尺寸不满足,可以通过`style`传入 height 自定义进度条高度
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 200 }}>
+        <Progress percent={10} stroke="#fc8800" />
+        <br />
+        <Progress percent={25} stroke="#f93920" />
+        <br />
+        <Progress percent={50} />
+        <br />
+        <Progress percent={80} />
+        <br />
+        <Progress percent={80} size="large" />
+        <br />
+        <Progress percent={80} style={{ height: '8px' }} />
+    </div>
+)
+```
+
+### 展示百分比文本
+
+通过`showInfo`控制是否展示百分比数字,可以通过`format`格式化展示文本
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 200 }}>
+        <Progress percent={10} stroke="#fc8800" showInfo={true} />
+        <br />
+        <Progress percent={25} stroke="#f93920" showInfo={true} />
+        <br />
+        <Progress percent={50} showInfo={true} />
+        <br />
+        <Progress percent={50} showInfo={true} format={percent => percent * 10 + '‰'} />
+    </div>
+)
+```
+
+### 垂直的进度条
+
+设置`direction='vertical'`,展示垂直进度条,可以通过`style`传入 width 控制进度条宽度
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ height: 100, display: 'flex' }}>
+        <Progress percent={10} direction="vertical" />
+        <Progress percent={25} direction="vertical" />
+        <Progress percent={50} direction="vertical" />
+        <Progress percent={80} direction="vertical" size="large" />
+        <Progress percent={80} direction="vertical" style={{ width: '8px' }} />
+    </div>
+)
+```
+
+### 环形进度条
+
+将 type 设为`circle`,进度条将会展示成环状。进度条默认尺寸为 72 x 72
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Progress percent={10} type="circle" style={{ margin: 5 }} />
+        <Progress percent={25} type="circle" style={{ margin: 5 }} />
+        <Progress percent={50} type="circle" style={{ margin: 5 }} />
+        <Progress percent={80} type="circle" style={{ margin: 5 }} />
+    </div>
+)
+```
+
+你可以通过修改`width`来控制环形进度条的大小
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <div>
+            <Progress percent={100} type="circle" width={100} style={{ margin: 5 }} />
+        </div>
+        <div>
+            <Progress percent={100} type="circle" width={100} style={{ margin: 5 }} stroke="#f93920" />
+        </div>
+    </React.Fragment>
+)
+```
+
+### 小号的环形进度条
+
+小号进度条默认尺寸为 24 x 24
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={10} type="circle" size="small" style={{ margin: 5 }} />
+        <Progress percent={25} type="circle" size="small" style={{ margin: 5 }} />
+        <Progress percent={50} type="circle" size="small" style={{ margin: 5 }} />
+        <Progress percent={80} type="circle" size="small" style={{ margin: 5 }} />
+    </React.Fragment>
+)
+```
+
+### 动态改变进度
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+import React, { useState } from 'react';
+import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
+
+() => {
+    const [percent, setPercent] = useState(40);
+    return (
+        <>
+            <div>
+                <Progress percent={percent} showInfo />
+                <Button
+                    icon={<IconChevronLeft />}
+                    theme="light"
+                    onClick={() => {
+                        setPercent(percent - 10);
+                    }}
+                    disabled={percent === 0}
+                />
+                <Button
+                    icon={<IconChevronRight />}
+                    theme="light"
+                    onClick={() => {
+                        setPercent(percent + 10);
+                    }}
+                    disabled={percent >= 100}
+                />
+            </div>
+        </>
+    );
+};
+```
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+import React, { useState } from 'react';
+import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
+
+() => {
+    const [cirPerc, setCirPerc] = useState(40);
+    return (
+        <div>
+            <div>
+                <Progress percent={cirPerc} type="circle" />
+            </div>
+            <Button
+                icon={<IconChevronLeft />}
+                theme="light"
+                onClick={() => {
+                    setCirPerc(cirPerc - 10);
+                }}
+                disabled={cirPerc === 0}
+            />
+            <Button
+                icon={<IconChevronRight />}
+                theme="light"
+                onClick={() => {
+                    setCirPerc(cirPerc + 10);
+                }}
+                disabled={cirPerc >= 100}
+            />
+        </div>
+    );
+};
+```
+
+### 自定义中心文字内容
+
+你可以通过传入 `format` 函数自定义中心文字,`format` 的入参为当前百分比  
+如果不需要中心文本内容,你可以将 `showInfo` 设为 false,或者在 `format` 中直接返回空字符串
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={75} showInfo type="circle" format={per => per + 'Days'} style={{ margin: 10 }} />
+        <Progress percent={100} showInfo type="circle" format={per => 'Done'} style={{ margin: 10 }} />
+        <Progress percent={50} showInfo type="circle" showInfo={false} style={{ margin: 10 }} />
+    </React.Fragment>
+)
+```
+
+### 圆角/方角边缘
+
+通过 strokeLinecap 属性,你可以控制环形进度条边缘形状
+
+```jsx live=true
+import React from 'react';
+import { Progress } from '@douyinfe/semi-ui';
+
+() => (
+    <React.Fragment>
+        <Progress percent={50} strokeLinecap="round" type="circle" style={{ margin: 10 }} />
+        <Progress percent={50} strokeLinecap="square" type="circle" style={{ margin: 10 }} />
+    </React.Fragment>
+)
+```
+
+## API 参考
+
+|属性 | 说明 | 类型 | 默认值 |
+|--- | --- | --- | --- |
+|className | 样式类名 | string |  |
+|direction | 条状进度条方向 `horizontal`、s`vertical` | string | 'horizontal' |
+|format | 格式化函数,入参为当前百分比,return 的结果将会直接渲染在圆形进度条中心 | (percent: number) => ReactNode | (percent) => percent + '%' |
+|orbitStroke | 进度条轨道填充色<br/>**v1.0.0 后提供** | string | 'var(--semi-color-fill-0)' |
+|percent | 进度百分比 | number |  |
+|showInfo | 环形进度条是否显示中间文本,条状进度条后右侧是否显示文本 | boolean | false |
+|size | 尺寸,可选`default`、`small`(仅 type=circle 生效)、`large`(仅 type=line 生效) | string | 'default' |
+|stroke | 进度条填充色 | string | 'var(--semi-color-success)' |
+|strokeLinecap | 圆角`round`/方角`square`(仅在 type='circle'模式下生效) | string | 'round' |
+|strokeWidth | type 为`line`时,该属性控制进度条高度; type 为`circle`时,该属性控制进度条宽度 | number | 4 |
+|style | 样式 | CSSProperties |  |
+|type | 类型,可选`line`、`circle` | string | 'line' |
+|width | 环形进度条宽度 | number | size='default'时为 72,'small'为 24 |
+
+## 设计变量
+
+<DesignToken/>

+ 387 - 0
content/feedback/skeleton/index-en-US.md

@@ -0,0 +1,387 @@
+---
+localeCode: en-US
+order: 64
+category: Feedback
+title:  Skeleton
+subTitle: Skeleton
+icon: doc-skeleton
+brief: A placeholder preview of content before the data loaded.
+---
+
+
+## Overview
+
+-   `Avatar`: Avatar placeholder, by default uses Avatar medium sizing: `width: 48px`, `height: 48px`. Supports other sizes after v1.0.
+-   `Image`: Image placeholder, default size: `width: 100%`, `height: 100%`.
+-   `Title`: Title placeholder, default size: `width: 100%`, `height: 24px`.
+-   `Paragraph`: Content part placeholder, default size: `width: 100%`, `height: 16px`, `margin-bottom: 10px`.
+-   `Button`: Button placeholder, default size: `width: 115px`, `height: 32px`.
+
+> Note: Default styles could by overwritten through `className` or `style`.
+
+## Demos
+
+### How to import
+
+```jsx
+import { Skeleton } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Switch, Button } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+  constructor() {
+    super();
+    this.state = {loading: true};
+  }
+
+  showContent() {
+    const {loading} = this.state;
+    this.setState({
+      loading: !loading
+    });
+  }
+
+  render() {
+    const {loading} = this.state;
+    return (
+      <>
+        <span style={{display: 'flex', alignItems: 'center'}}>
+          <Switch onChange={() => this.showContent()}/>
+          <span style={{marginLeft: '10px' }}>Show Loading Content</span>
+        </span>
+        <br/>
+        <Skeleton placeholder={(<Skeleton.Avatar />)} loading={loading}>
+            <Avatar color='blue' style={{marginBottom: 10}}>U</Avatar>
+        </Skeleton>
+        <br/>
+        <Skeleton style={{width: 200, height: 150}} placeholder={(<Skeleton.Image />)} loading={loading}>
+            <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" height='150' />
+        </Skeleton>
+        <br/>
+        <Skeleton style={{width: 80}} placeholder={(<Skeleton.Title style={{marginBottom: 10}}/>)} loading={loading}>
+            <h4 style={{marginBottom: 0}}>Semi UI</h4>
+        </Skeleton>
+        <Skeleton style={{width: 240}} placeholder={(<Skeleton.Paragraph rows={2}/>)} loading={loading}>
+            <p style={{width: 240}} >Carefully polish the user experience of each component.</p>
+        </Skeleton>
+        <br/>
+        <Skeleton placeholder={(<Skeleton.Button />)} loading={loading}>
+            <Button>Button</Button>
+        </Skeleton>
+      </>
+    );
+  }
+}
+```
+
+### Combinations
+
+Image and caption.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton } from '@douyinfe/semi-ui';
+
+() => {
+  const placeholder = (
+    <div>
+      <Skeleton.Image style={{width: 200, height: 150}}/>
+      <Skeleton.Title style={{width: 120, marginTop: 10}}/>
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true}>
+      <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" height='150' />
+      <h4>Semi UI</h4>
+    </Skeleton>
+  )
+}
+```
+
+Statistics.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Descriptions } from '@douyinfe/semi-ui';
+
+() => {
+  const placeholder = (
+    <div>
+      <Skeleton.Paragraph rows={1} style={{width: 80, marginBottom: 10}}/>
+      <Skeleton.Title style={{width: 120}}/>
+    </div>
+  );
+
+  const data = [
+    { key: 'Actual User', value: '1,480,000' },
+  ];
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true}>
+      <Descriptions data={data} row />
+    </Skeleton>
+  )
+}
+```
+
+Avatar and title.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+  const placeholder = (
+    <div style={{display: 'flex', alignItems: 'center'}}>
+      <Skeleton.Avatar style={{marginRight: 12}}/>
+      <Skeleton.Title style={{width: 120}}/>
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true}>
+      <Avatar color='blue' style={{marginRight: 12}}>UI</Avatar>
+      <span>Semi UI</span>
+    </Skeleton>
+  )
+}
+```
+
+Centered paragraphs and button.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Button } from '@douyinfe/semi-ui';
+
+() => {
+  const style = {
+    display: 'flex',
+    flexDirection: 'column',
+    alignItems: 'center',
+    width: '300px',
+    marginBottom: '10px',
+  }
+
+  const placeholder = (
+    <div style={style}>
+      <Skeleton.Paragraph style={style} rows={3}/>
+      <Skeleton.Button />
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true} style={{textAlign: 'center'}}>
+      <div style={{textAlign: 'center'}}>
+        <p>Hi, Bytedance dance dance.</p>
+        <p>Hi, Bytedance dance dance.</p>
+        <Button>Button</Button>
+      </div>
+    </Skeleton>
+  )
+}
+```
+
+Avatar, headline and paragraph.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+  const style = {
+    display: 'flex',
+    alignItems: 'flex-start'
+  }
+
+  const placeholder = (
+    <div style={style}>
+      <Skeleton.Avatar style={{marginRight: 12}}/>
+      <div>
+      <Skeleton.Title style={{width: 120, marginBottom: 12, marginTop: 12}}/>
+      <Skeleton.Paragraph style={{width: 240}} rows={3}/>
+      </div>
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true}>
+    <div style={style}>
+      <Avatar color='blue' style={{marginRight: 12}}>UI</Avatar>
+      <div>
+        <h3>Semi UI</h3>
+        <p>Hi, Bytedance dance dance.</p>
+        <p>Hi, Bytedance dance dance.</p>
+        <p>Hi, Bytedance dance dance.</p>
+      </div>
+      </div>
+    </Skeleton>
+  )
+}
+```
+
+Table.
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Table } from '@douyinfe/semi-ui';
+
+() => {
+  const data = {
+        columns: [
+        {
+            title: 'Name',
+            dataIndex: 'name',
+        },
+        {
+            title: 'Age',
+            dataIndex: 'age',
+        },
+        {
+            title: 'Address',
+            dataIndex: 'address',
+        },
+    ],
+      content: [{
+            key: '1',
+            name: 'John Brown',
+            age: 32,
+            address: 'New York No. 1 Lake Park, New York No. 1 Lake Park',
+        },
+        {
+            key: '2',
+            name: 'Jim Green',
+            age: 42,
+            address: 'London No. 1 Lake Park',
+        },
+        {
+            key: '3',
+            name: 'Joe Black',
+            age: 32,
+            address: 'Sidney No. 1 Lake Park',
+        },
+        {
+            key: '4',
+            name: 'Disabled User',
+            age: 99,
+            address: 'Sidney No. 1 Lake Park',
+        },
+    ]
+  }
+
+  const skData = {
+    columns: [1,2,3].map(key => {
+      const item = {};
+      item.title = (<Skeleton.Title style={{width: '0'}}/>)
+      item.dataIndex = key;
+      return item;
+    }),
+    dataSource: [1,2,3,4].map(key => {
+      const item = {};
+      item.key = key;
+      [1,2,3].forEach(i => {
+        const width = 50 * i;
+        item[i] = (<Skeleton.Paragraph style={{width: width}} rows={1}/>)
+      })
+      return item;
+    })
+  };
+
+  const placeholder = (
+    <div style={{position: 'relative'}}>
+      <Table
+        style={{backgroundColor: 'var(--semi-color-bg-1)'}}
+        columns={skData.columns}
+        dataSource={skData.dataSource}
+        pagination={false}
+      />
+      <div style={{position: 'absolute', left: 0, right: 0, top: 0, bottom: 0}}></div>
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true}>
+    <div>
+      <Table columns={data.columns} dataSource={data.content} pagination={false} />
+    </div>
+    </Skeleton>
+  )
+}
+```
+
+### Animated Loading
+
+Use `active` property to display animated loading effects.
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+  const style = {
+    display: 'flex',
+    alignItems: 'flex-start'
+  }
+
+  const placeholder = (
+    <div style={style}>
+      <Skeleton.Avatar style={{marginRight: 12}}/>
+      <div>
+      <Skeleton.Title style={{width: 120, marginBottom: 12, marginTop: 12}}/>
+      <Skeleton.Paragraph style={{width: 240}} rows={3}/>
+      </div>
+    </div>
+  );
+
+  return (
+    <Skeleton placeholder={placeholder} loading={true} active>
+    <div style={style}>
+      <Avatar color='blue' style={{marginRight: 12}}>UI</Avatar>
+      <div>
+        <h3>Semi UI</h3>
+        <p>Hi, Bytedance dance dance.</p>
+        <p>Hi, Bytedance dance dance.</p>
+        <p>Hi, Bytedance dance dance.</p>
+      </div>
+      </div>
+    </Skeleton>
+  )
+}
+```
+
+## API reference
+
+### Skeleton
+
+| Property    | Instructions                                                                                  | type       | Default |
+| ----------- | --------------------------------------------------------------------------------------------- | ---------- | ------- |
+| active      | Toggle whether to show the animated loading effect                                            | boolean    | false   |
+| class Name  | Class name                                                                                    | string     | -       |
+| loading     | When set to true, the placeholder element is displayed. Otherwise, child element is displayed | boolean    | true    |
+| placeholder | Elements to be displayed while loading                                                        | ReactNode | -       |
+| style       | Inline style                                                                                  | CSSProperties     | -       |
+
+### Skeleton.Avatar
+
+> `Skeleton.Image`,`Skeleton.Title`,`Skeleton.Button` have same APIs with `Skeleton.Avatar`.
+
+| Property   | Instructions | type   | Default |
+| ---------- | ------------ | ------ | ------- |
+| class Name | Class name   | string | -       |
+| size       | Size of the avatar, one of `extra-extra-small`, `extra-small`, `small`, `medium`, `large`, `extra-large`, **v>=1.0** | string | `medium` |
+| style      | Inline style | CSSProperties | -       |
+
+### Skeleton.Paragraph
+
+| Property  | Instructions                                        | type   | Default |
+| --------- | --------------------------------------------------- | ------ | ------- |
+| className | Class name                                          | string | -       |
+| rows      | Set the number of rows in the placeholder paragraph | number | 4       |
+| style     | Inline style                                        | CSSProperties | -       |
+
+## Design Tokens
+<DesignToken/>

+ 393 - 0
content/feedback/skeleton/index.md

@@ -0,0 +1,393 @@
+---
+localeCode: zh-CN
+order: 64
+category: 反馈类
+title: Skeleton 骨架屏
+icon: doc-skeleton
+brief: 在需要等待加载内容的位置提供的占位组件。
+---
+
+## 概述
+
+-   `Avatar`:占位头像,默认为圆形,默认尺寸:Avatar medium: `width: 48px`,`height: 48px`。支持 Avatar 的 size 属性 (**v>=1.0**)
+-   `Image`:占位图像,默认尺寸:`width: 100%`,`height: 100%`。
+-   `Title`:占位标题,默认尺寸:`width: 100%`, `height: 24px`。
+-   `Paragraph`:占位内容部分,默认尺寸:`width: 100%`,`height: 16px`,`margin-bottom: 10px`。
+-   `Button`:占位按钮,默认尺寸:`width: 115px`,`height: 32px`。
+
+> 注意:默认样式均可通过 `className` 或 `style` 进行自定义。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Skeleton } from '@douyinfe/semi-ui';
+```
+
+### 基本使用
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Skeleton, Switch, Avatar, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const [loading, setLoading] = useState(true);
+    const showContent = () => {
+        setLoading(!loading);
+    };
+    return (
+      <>
+          <span style={{ display: 'flex', alignItems: 'center' }}>
+              <Switch onChange={() => showContent()} />
+              <span style={{ marginLeft: '10px' }}>显示加载内容</span>
+          </span>
+          <br />
+          <Skeleton placeholder={<Skeleton.Avatar />} loading={loading}>
+              <Avatar color="blue" style={{ marginBottom: 10 }}>
+                  U
+              </Avatar>
+          </Skeleton>
+          <br />
+          <Skeleton style={{ width: 200, height: 150 }} placeholder={<Skeleton.Image />} loading={loading}>
+              <img
+                  src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"
+                  height="150"
+              />
+          </Skeleton>
+          <br />
+          <Skeleton
+              style={{ width: 80 }}
+              placeholder={<Skeleton.Title style={{ marginBottom: 10 }} />}
+              loading={loading}
+          >
+              <h4 style={{ marginBottom: 0 }}>Semi UI</h4>
+          </Skeleton>
+          <Skeleton style={{ width: 240 }} placeholder={<Skeleton.Paragraph rows={2} />} loading={loading}>
+              <p style={{ width: 240 }}>精心打磨每一个组件的用户体验,从用户的角度考虑每个组件的使用场景。</p>
+          </Skeleton>
+          <br />
+          <Skeleton placeholder={<Skeleton.Button />} loading={loading}>
+              <Button>Button</Button>
+          </Skeleton>
+      </>
+    )
+}
+```
+
+### 组合使用
+
+图片和标题。
+
+```jsx live=true
+import React from 'react';
+import { Skeleton } from '@douyinfe/semi-ui';
+
+() => {
+    const placeholder = (
+        <div>
+            <Skeleton.Image style={{ width: 200, height: 150 }} />
+            <Skeleton.Title style={{ width: 120, marginTop: 10 }} />
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true}>
+            <img
+                src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"
+                height="150"
+            />
+            <h4>Semi UI</h4>
+        </Skeleton>
+    );
+};
+```
+
+统计数字。
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Descriptions } from '@douyinfe/semi-ui';
+
+() => {
+    const placeholder = (
+        <div>
+            <Skeleton.Paragraph rows={1} style={{ width: 80, marginBottom: 10 }} />
+            <Skeleton.Title style={{ width: 120 }} />
+        </div>
+    );
+
+    const data = [{ key: '实际用户数量', value: '1,480,000' }];
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true}>
+            <Descriptions data={data} row />
+        </Skeleton>
+    );
+};
+```
+
+头像和标题。
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+    const placeholder = (
+        <div style={{ display: 'flex', alignItems: 'center' }}>
+            <Skeleton.Avatar style={{ marginRight: 12 }} />
+            <Skeleton.Title style={{ width: 120 }} />
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true}>
+            <Avatar color="blue" style={{ marginRight: 12 }}>
+                UI
+            </Avatar>
+            <span>Semi UI</span>
+        </Skeleton>
+    );
+};
+```
+
+居中段落和按钮。
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const style = {
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'center',
+        width: '300px',
+        marginBottom: '10px',
+    };
+
+    const placeholder = (
+        <div style={style}>
+            <Skeleton.Paragraph style={style} rows={3} />
+            <Skeleton.Button />
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true} style={{ textAlign: 'center' }}>
+            <div style={{ textAlign: 'center' }}>
+                <p>Hi, Bytedance dance dance.</p>
+                <p>Hi, Bytedance dance dance.</p>
+                <Button>Button</Button>
+            </div>
+        </Skeleton>
+    );
+};
+```
+
+头像、标题和段落。
+
+```jsx live=true
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+    const style = {
+        display: 'flex',
+        alignItems: 'flex-start',
+    };
+
+    const placeholder = (
+        <div style={style}>
+            <Skeleton.Avatar style={{ marginRight: 12 }} />
+            <div>
+                <Skeleton.Title style={{ width: 120, marginBottom: 12, marginTop: 12 }} />
+                <Skeleton.Paragraph style={{ width: 240 }} rows={3} />
+            </div>
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true}>
+            <div style={style}>
+                <Avatar color="blue" style={{ marginRight: 12 }}>
+                    UI
+                </Avatar>
+                <div>
+                    <h3>Semi UI</h3>
+                    <p>Hi, Bytedance dance dance.</p>
+                    <p>Hi, Bytedance dance dance.</p>
+                    <p>Hi, Bytedance dance dance.</p>
+                </div>
+            </div>
+        </Skeleton>
+    );
+};
+```
+
+表格。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Skeleton, Table } from '@douyinfe/semi-ui';
+
+() => {
+    const data = {
+        columns: [
+            {
+                title: 'Name',
+                dataIndex: 'name',
+            },
+            {
+                title: 'Age',
+                dataIndex: 'age',
+            },
+            {
+                title: 'Address',
+                dataIndex: 'address',
+            },
+        ],
+        content: [
+            {
+                key: '1',
+                name: 'John Brown',
+                age: 32,
+                address: 'New York No. 1 Lake Park, New York No. 1 Lake Park',
+            },
+            {
+                key: '2',
+                name: 'Jim Green',
+                age: 42,
+                address: 'London No. 1 Lake Park',
+            },
+            {
+                key: '3',
+                name: 'Joe Black',
+                age: 32,
+                address: 'Sidney No. 1 Lake Park',
+            },
+            {
+                key: '4',
+                name: 'Disabled User',
+                age: 99,
+                address: 'Sidney No. 1 Lake Park',
+            },
+        ],
+    };
+
+    const skData = {
+        columns: [1, 2, 3].map(key => {
+            const item = {};
+            item.title = <Skeleton.Title style={{ width: '0' }} />;
+            item.dataIndex = `${key}`;
+            return item;
+        }),
+        dataSource: [1, 2, 3, 4].map(key => {
+            const item = {};
+            item.key = key;
+            [1, 2, 3].forEach(i => {
+                const width = 50 * i;
+                item[i] = <Skeleton.Paragraph style={{ width: width }} rows={1} />;
+            });
+            return item;
+        }),
+    };
+
+    const placeholder = (
+        <div style={{ position: 'relative' }}>
+            <Table
+                style={{ backgroundColor: 'var(--semi-color-bg-1)' }}
+                columns={skData.columns}
+                dataSource={skData.dataSource}
+                pagination={false}
+            />
+            <div style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }}></div>
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true}>
+            <div>
+                <Table columns={data.columns} dataSource={data.content} pagination={false} />
+            </div>
+        </Skeleton>
+    );
+};
+```
+
+### 加载动画
+
+通过设置 `active` 属性可以展示动画效果。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Skeleton, Avatar } from '@douyinfe/semi-ui';
+
+() => {
+    const style = {
+        display: 'flex',
+        alignItems: 'flex-start',
+    };
+
+    const placeholder = (
+        <div style={style}>
+            <Skeleton.Avatar style={{ marginRight: 12 }} />
+            <div>
+                <Skeleton.Title style={{ width: 120, marginBottom: 12, marginTop: 12 }} />
+                <Skeleton.Paragraph style={{ width: 240 }} rows={3} />
+            </div>
+        </div>
+    );
+
+    return (
+        <Skeleton placeholder={placeholder} loading={true} active>
+            <div style={style}>
+                <Avatar color="blue" style={{ marginRight: 12 }}>
+                    UI
+                </Avatar>
+                <div>
+                    <h3>Semi UI</h3>
+                    <p>Hi, Bytedance dance dance.</p>
+                    <p>Hi, Bytedance dance dance.</p>
+                    <p>Hi, Bytedance dance dance.</p>
+                </div>
+            </div>
+        </Skeleton>
+    );
+};
+```
+
+## API 参考
+
+### Skeleton
+
+| 属性        | 说明                                       | 类型       | 默认值 |
+| ----------- | ------------------------------------------ | ---------- | ------ |
+| active      | 是否展示动画效果                           | boolean    | false  |
+| className   | 类名                                       | string     | -      |
+| loading     | 为 true 时,显示占位元素。反之则显示子组件 | boolean    | true   |
+| placeholder | 加载等待时的占位元素                       | ReactNode | -      |
+| style       | 样式                                       | CSSProperties     | -      |
+
+### Skeleton.Avatar
+
+> `Skeleton.Image`,`Skeleton.Title`,`Skeleton.Button` API 与 `Skeleton.Avatar` 相同
+
+| 属性 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| className | 类名 | string | - |
+| size | 设置头像的大小,支持 `extra-extra-small`, `extra-small`、`small`、`medium`、`large`、`extra-large` **v>=1.0** | string | `medium` |
+| style | 样式 | CSSProperties | - |
+
+### Skeleton.Paragraph
+
+| 属性      | 说明                 | 类型   | 默认值 |
+| --------- | -------------------- | ------ | ------ |
+| className | 类名                 | string | -      |
+| rows      | 设置段落占位图的行数 | number | 4      |
+| style     | 样式                 | CSSProperties | -      |
+
+## 设计变量
+
+<DesignToken/>

+ 177 - 0
content/feedback/spin/index-en-US.md

@@ -0,0 +1,177 @@
+---
+localeCode: en-US
+order: 65
+category: Feedback
+title: Spin
+subTitle: Spin
+icon: doc-spin
+brief: Spin is used to inform the user that the content is loading and may take an uncertain period of time.
+---
+
+## Demos
+
+### How to import
+
+```jsx
+import { Spin } from '@douyinfe/semi-ui';
+```
+
+### Basic usage
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div style={{ marginBottom: 10 }}>A basic spin.</div>
+        <Spin />
+    </div>
+);
+```
+
+### Size
+
+Supports three sizes: `large`, `medium` (default), and `small`.
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div style={{ marginBottom: 5 }}>size: small</div>
+        <Spin size="small" />
+        <br />
+        <br />
+        <div style={{ marginBottom: 10 }}>size: middle</div>
+        <Spin size="middle" />
+        <br />
+        <br />
+        <div style={{ marginBottom: 15 }}>size: large</div>
+        <Spin size="large" />
+    </div>
+);
+```
+
+### With Description
+
+Use `tip` to set the description texts when Spin is used as a wrapping element
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Spin tip="I am loading...">
+            <div
+                style={{
+                    border: '1px solid var(--semi-color-primary)',
+                    borderRadius: '4px',
+                    paddingLeft: '8px',
+                }}
+            >
+                <p>Here are some texts.</p>
+                <p>And more texts on the way.</p>
+            </div>
+        </Spin>
+    </div>
+);
+```
+
+### Customized Indicator
+
+Use `indicator` property to customize Spin's indicator style.
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+import { IconLoading } from '@douyinfe/semi-icons';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div>A spin with customized indicator.</div>
+        <Spin indicator={<IconLoading />} />
+    </div>
+);
+```
+
+### Delay
+
+Delayed to display Spin.
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => {
+    const [loading, toggleLoading] = useState(false);
+
+    const toggle = () => {
+        toggleLoading(!loading);
+    };
+    return (
+        <div>
+            <Button onClick={toggle} style={{ marginRight: 20 }}>
+                Delayed spin
+            </Button>
+            <Spin delay={1000} spinning={loading}></Spin>
+        </div>
+    );
+};
+```
+
+### Controlled
+
+Use `spinning` to determine if the component is in loading status
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => {
+    const [loading, toggleLoading] = useState(false);
+
+    const toggle = () => {
+        toggleLoading(!loading);
+    };
+    return (
+        <div>
+            <Button onClick={toggle} style={{ marginRight: 20 }}>
+                Controlled Spin
+            </Button>
+            <Spin spinning={loading}></Spin>
+        </div>
+    );
+};
+```
+
+## API Reference
+
+| Properties       | Instructions                                              | type       | Default  |
+| ---------------- | --------------------------------------------------------- | ---------- | -------- |
+| childStyle       | Inline style for children element **v>=1.0.0**            | CSSProperties     | -        |
+| delay            | Delay timing to display Spin                              | number(ms) | 0        |
+| indicator        | Indicators                                                | ReactNode  | -        |
+| size             | Size, one of `small`, `middle`, `large`                   | string     | `middle` |
+| spinning         | Toggle whether it is in loading                           | boolean    | true     |
+| style            | Inline style                                              | CSSProperties     | -        |
+| tip              | Description texts when Spin is used as a wrapping element | string     | -        |
+| wrapperClassName | Class name of wrapping element                            | string     | -        |
+
+## Design Tokens
+
+<DesignToken/>
+
+## FAQ
+
+-   **How to modify the color of the spin icon? **
+
+    You can overwrite the original color by adding a color property to the .semi-spin-wrapper class.
+
+    ```
+    .semi-spin-wrapper {
+      color: red;
+    }
+    ```

+ 152 - 0
content/feedback/spin/index.md

@@ -0,0 +1,152 @@
+---
+localeCode: zh-CN
+order: 65
+category: 反馈类
+title: Spin 加载器
+icon: doc-spin
+brief: 加载器组件用于告知用户内容正在加载且需要一段不确定的时长。
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Spin } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div style={{ marginBottom: 10 }}>A basic spin.</div>
+        <Spin />
+    </div>
+);
+```
+
+### 尺寸
+
+组件定义了三种尺寸:大、中(默认)、小。
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div style={{ marginBottom: 5 }}>size: small</div>
+        <Spin size="small" />
+        <br />
+        <br />
+        <div style={{ marginBottom: 10 }}>size: middle</div>
+        <Spin size="middle" />
+        <br />
+        <br />
+        <div style={{ marginBottom: 15 }}>size: large</div>
+        <Spin size="large" />
+    </div>
+);
+```
+
+### 带文字的
+
+通过 `tip` 属性可设置当 Spin 用作包裹元素时的文字。
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Spin tip="I am loading...">
+            <div
+                style={{
+                    border: '1px solid var(--semi-color-primary)',
+                    borderRadius: '4px',
+                    paddingLeft: '8px',
+                }}
+            >
+                <p>Here are some texts.</p>
+                <p>And more texts on the way.</p>
+            </div>
+        </Spin>
+    </div>
+);
+```
+
+### 自定义指示符
+
+可以通过设置 `indicator` 属性自定义 Spin 的指示符样式。
+
+```jsx live=true
+import React from 'react';
+import { Spin } from '@douyinfe/semi-ui';
+import { IconLoading } from '@douyinfe/semi-icons';
+
+() => (
+    <div style={{ marginLeft: 30 }}>
+        <div>A spin with customized indicator.</div>
+        <Spin indicator={<IconLoading />} />
+    </div>
+);
+```
+
+### 延迟显示
+
+通过 delay 设置延迟显示 `loading` 的效果  
+组件是否处于 `loading` 状态由传入的 `spinning` 值决定,loading 为受控属性
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { Spin, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const [loading, toggleLoading] = useState(false);
+
+    const toggle = () => {
+        toggleLoading(!loading);
+    };
+    return (
+        <div>
+            <Button onClick={toggle} style={{ marginRight: 20 }}>
+                延迟显示的spin
+            </Button>
+            <Spin delay={1000} spinning={loading}></Spin>
+        </div>
+    );
+};
+```
+
+## API 参考
+
+| 属性             | 说明                                          | 类型       | 默认值   |
+| ---------------- | --------------------------------------------- | ---------- | -------- |
+| childStyle       | 内部子元素的样式 **v>=1.0.0**                 | CSSProperties     | -        |
+| delay            | 延迟显示加载效果的时间                        | number(ms) | 0        |
+| indicator        | 加载指示符                                    | ReactNode  | 无       |
+| size             | 组件大小,可选值为 `small`, `middle`, `large` | string     | `middle` |
+| spinning         | 是否处于加载中的状态                          | boolean    | true     |
+| style            | 内联样式                                      | CSSProperties     | -        |
+| tip              | 当 spin 作为包裹元素时,可以自定义描述文字    | string     | 无       |
+| wrapperClassName | 包裹元素的类名                                | string     | 无       |
+
+## 设计变量
+
+<DesignToken/>
+
+## FAQ
+
+-   **怎么修改 icon 的颜色?**
+
+    可以通过给 .semi-spin-wrapper 类添加 color 属性覆盖原有的颜色。
+
+    ```
+    .semi-spin-wrapper {
+      color: red;
+    }
+    ```

+ 411 - 0
content/feedback/toast/index-en-US.md

@@ -0,0 +1,411 @@
+---
+localeCode: en-US
+order: 66
+category: Feedback
+title: Toast
+subTitle: Toast
+icon: doc-toast
+width: 65%
+brief: Toast component is used to give timely feedback to user's operations. It could be the result feedback of the operation, such as success, failure, error, warning, etc.
+---
+
+## Demos
+
+### How to import
+
+```jsx
+import { Toast } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+import { throttle } from 'lodash-es';
+
+function Demo() {
+    const opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+    };
+
+    const handleClose = () => {
+        throttled.cancel();
+    };
+    const throttleOpts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 10,
+        onClose: handleClose,
+    };
+    const throttled = throttle(() => Toast.info(throttleOpts), 10000, { trailing: false });
+
+    return (
+        <div>
+            <Button onClick={() => Toast.info(opts)}>Display Toast</Button>
+            <br />
+            <br />
+            <Button onClick={throttled}>Throttled Toast</Button>
+        </div>
+    );
+}
+render(Demo);
+```
+
+### Other Types
+
+Use different methods to show different Toast including success, warning, error and info.
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.success('Hi,Bytedance dance dance')}>Success</Button>
+            <br />
+            <br />
+            <Button type="warning" onClick={() => Toast.warning(opts)}>
+                Warning
+            </Button>
+            <br />
+            <br />
+            <Button type="danger" onClick={() => Toast.error(opts)}>
+                Error
+            </Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### Colored Background
+
+You could use `theme` for a colored background style. Default is `normal`.
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+        theme: 'light',
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.info(opts)}>Info</Button>
+            <br />
+            <br />
+            <Button onClick={() => Toast.success(opts)}>Success</Button>
+            <br />
+            <br />
+            <Button type="warning" onClick={() => Toast.warning(opts)}>
+                Warning
+            </Button>
+            <br />
+            <br />
+            <Button type="danger" onClick={() => Toast.error(opts)}>
+                Error
+            </Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### Custom Children with Link
+
+Informational feedback
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Typography, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const { Text } = Typography;
+
+    let opts = {
+        content: (
+            <span>
+                <Text>Hi, Bytedance dance dance</Text>
+                <Text link style={{ marginLeft: 12 }}>
+                    More Info
+                </Text>
+            </span>
+        ),
+        duration: 3,
+    };
+
+    let multiLineOpts = {
+        content: (
+            <>
+                <div>Hi, Bytedance dance dance</div>
+                <div style={{ marginTop: 8 }}>
+                    <Text link>More Info</Text>
+                    <Text link style={{ marginLeft: 20 }}>
+                        Later
+                    </Text>
+                </div>
+            </>
+        ),
+        duration: 3,
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.info(opts)}>Display Toast</Button>
+            <br />
+            <br />
+            <Button onClick={() => Toast.info(multiLineOpts)}>Display Multi-line Toast</Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### Delay
+
+Use `duration` to set up time delay. By default it closes after 3 seconds.
+
+```jsx live=true noInline=true hideInDSM
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 10,
+    };
+
+    return <Button onClick={() => Toast.info(opts)}>Close After 10s</Button>;
+}
+render(Demo);
+```
+
+### Manual Close
+
+Set `duration` to 0 if you do not want the Notification to close by itself. In this case, it could only be closed manually.
+
+```jsx live=true noInline=true hideInDSM
+import React, { useState } from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [toastId, setToastId] = useState();
+    function show() {
+        if (toastId) {
+            return;
+        }
+        let id = Toast.info(opts);
+        setToastId(id);
+    }
+    function hide() {
+        Toast.close(toastId);
+        destroy();
+    }
+    function destroy() {
+        setToastId(null);
+    }
+    let opts = {
+        content: 'Not auto close',
+        duration: 0,
+        onClose: destroy,
+    };
+    return (
+        <>
+            <Button type="primary" onClick={show}>
+                Show Toast
+            </Button>
+            <br />
+            <br />
+            <Button type="primary" onClick={hide}>
+                Hide Toast
+            </Button>
+        </>
+    );
+}
+
+render(Demo);
+```
+
+### useToast Hooks
+
+You could use `Toast.useToast` to create a `contextHolder` that could access context. Created toast will be inserted to where contextHolder is placed.
+
+```jsx live=true noInline=true hideInDSM
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+const ReachableContext = React.createContext();
+
+function Demo(props = {}) {
+    const [toast, contextHolder] = Toast.useToast();
+    const config = {
+        duration: 0,
+        title: 'This is a success message',
+        content: <ReachableContext.Consumer>{name => `ReachableContext: ${name}`}</ReachableContext.Consumer>,
+    };
+
+    return (
+        <ReachableContext.Provider value="Light">
+            <div>
+                <Button
+                    onClick={() => {
+                        toast.success(config);
+                    }}
+                >
+                    Hook Toast
+                </Button>
+            </div>
+            {contextHolder}
+        </ReachableContext.Provider>
+    );
+}
+
+render(Demo);
+```
+
+You could also use `ReactDOM.createPortal` to insert toast in a Portal.
+
+```jsx live=true noInline=true
+import React, { useRef } from 'react';
+import { Toast } from '@douyinfe/semi-ui';
+
+const ReachableContext = React.createContext();
+
+const useCreatePortalInBody = () => {
+    const wrapperRef = useRef(null);
+    if (wrapperRef.current === null && typeof document !== 'undefined') {
+        const div = document.createElement('div');
+        wrapperRef.current = div;
+    }
+    useLayoutEffect(() => {
+        const wrapper = wrapperRef.current;
+        if (!wrapper || typeof document === 'undefined') {
+            return;
+        }
+        document.querySelector('.article-wrapper').appendChild(wrapper);
+        return () => {
+            document.querySelector('.article-wrapper').appendChild(wrapper);
+        };
+    }, []);
+    return children => wrapperRef.current && ReactDOM.createPortal(children, wrapperRef.current);
+};
+
+function Demo(props = {}) {
+    const [toast, contextHolder] = Toast.useToast();
+    const createBodyPortal = useCreatePortalInBody();
+    const config = {
+        duration: 3,
+        title: 'This is a success message',
+        content: <ReachableContext.Consumer>{name => `ReachableContext: ${name}`}</ReachableContext.Consumer>,
+    };
+
+    return (
+        <ReachableContext.Provider value="Light">
+            <div>
+                <Button
+                    onClick={() => {
+                        toast.success(config);
+                    }}
+                >
+                    Hook Toast
+                </Button>
+            </div>
+            {createBodyPortal(
+                <div style={{ position: 'fixed', top: 0, left: '50%', zIndex: 10000 }}>{contextHolder}</div>
+            )}
+        </ReachableContext.Provider>
+    );
+}
+
+render(Demo);
+```
+
+## API Reference
+
+The static methods provided are as follows: Display: You can pass in `options` object or string directly. Methods return the value of `toastId`: `const toastId = Toast.info({ /*...options*/ })`
+
+-   `Toast.info(options || string)`
+-   `Toast.error(options || string)`
+-   `Toast.warning(options || string)`
+-   `Toast.success(options || string)`
+
+Close Manually ( `toastId` is the return value of the display methods)
+
+-   `Toast.close(toastId)`
+
+| Properties | Instructions | type | Default | version |
+| --- | --- | --- | --- | --- |
+| bottom | Pop-up position bottom | number \| string | - | 0.25.0 |
+| content | Toast content | string | ReactNode | '' |  |
+| duration | Automatic close delay, no auto-close when set to 0 | number | 3 |  |
+| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | () => HTMLElement \| null | () => document.body | 0.34.0 |
+| icon | Custom icons | ReactNode |  | 0.25.0 |
+| left | Pop-up position left | number \| string | - | 0.25.0 |
+| right | Pop-up position right | number \| string | - | 0.25.0 |
+| showClose | Toggle Whether show close button | boolean | true | 0.25.0 |
+| textMaxWidth | Maximum width of content | number \| string | 450 | 0.25.0 |
+| theme | Style of background fill, one of `light`, `normal` | string | `normal` | 1.0.0 |
+| top | Pop-up position top | number \| string | - | 0.25.0 |
+| zIndex | Z-index value | number | 1010 |  |
+| onClose | Callback function when closing toast | () => void |  |  |
+
+The global configuration is set before any method call, and takes effect only once (>= 0.25.0):
+
+-   `Toast.config(config)`
+
+| Properties | Instructions | type | Default | version |
+| --- | --- | --- | --- | --- |
+| bottom | Bottom, absolute position | number \| string | - | 0.25.0 |
+| duration | Automatic close delay, no auto-close when set to 0 | number(second) | 3 | 0.25.0 |
+| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | () => HTMLElement \| null | () => document.body | 1.23.0 |
+| left | Left, absolute position | number \| string | - | 0.25.0 |
+| right | Right, absolute position | number \| string | - | 0.25.0 |
+| top | Top, absolute position | number \| string | - | 0.25.0 |
+| zIndex | Z-index | number | 1010 | 0.25.0 |
+
+-   `ToastFactory.create(config) => Toast`  
+    If you need Toast with different configs in your application, you can use ToastFactory.create(config)to create a new Toast (>= 1.23):
+
+```jsx live=true noInline=true
+function Demo() {
+    const ToastInCustomContainer = ToastFactory.create({
+        getPopupContainer: () => document.getElementById('custom-toast-container'),
+    });
+    return (
+        <div>
+            <Button onClick={() => Toast.info('Toast')}>Default Toast</Button>
+            <br />
+            <br />
+            <Button onClick={() => ToastInCustomContainer.info('Toast in some container')}>
+                Toast in custom container
+            </Button>
+            <div id="custom-toast-container">custom container</div>
+        </div>
+    );
+}
+render(Demo);
+```
+
+Globally Destroy (>= 0.25.0):
+
+-   `Toast.destroyAll()`
+
+HookToast
+
+-   `Toast.useToast` **v>=1.2.0**  
+    When you need access Context, you could use `Toast.useToast` to create a `contextHolder` and insert to corresponding DOM tree. Toast created by hooks will be able to access the context where `contextHolder` is inserted. Hook toast has following methods: `info`, `success`, `warning`, `error`, `close`.
+
+## Design Tokens
+
+<DesignToken/>

+ 413 - 0
content/feedback/toast/index.md

@@ -0,0 +1,413 @@
+---
+localeCode: zh-CN
+order: 66
+category: 反馈类
+title: Toast 提示
+icon: doc-toast
+width: 65%
+brief: Toast 提示是对用户的操作做出及时反馈,由用户的操作触发,反馈信息可以是操作的结果状态,如成功、失败、出错、警告等。
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Toast } from '@douyinfe/semi-ui';
+```
+
+### 普通提示
+
+信息提醒反馈
+
+```jsx live=true noInline=true
+import React from 'react';
+import { throttle } from 'lodash-es';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+    };
+
+    const handleClose = () => {
+        throttled.cancel();
+    };
+    const throttleOpts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 10,
+        onClose: handleClose,
+    };
+    const throttled = throttle(() => Toast.info(throttleOpts), 10000, { trailing: false });
+
+    return (
+        <div>
+            <Button onClick={() => Toast.info(opts)}>Display Toast</Button>
+            <br />
+            <br />
+            <Button onClick={throttled}>Throttled Toast</Button>
+        </div>
+    );
+}
+render(Demo);
+```
+
+### 其他提示类型
+
+包括成功、失败、警告
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.success('Hi,Bytedance dance dance')}>Success</Button>
+            <br />
+            <br />
+            <Button type="warning" onClick={() => Toast.warning(opts)}>
+                Warning
+            </Button>
+            <br />
+            <br />
+            <Button type="danger" onClick={() => Toast.error(opts)}>
+                Error
+            </Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### 多色样式
+
+可以使用 `theme` 设置浅色填充样式提高与界面的对比,默认为 'normal' 的白色模式。
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 3,
+        theme: 'light',
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.info(opts)}>Info</Button>
+            <br />
+            <br />
+            <Button onClick={() => Toast.success(opts)}>Success</Button>
+            <br />
+            <br />
+            <Button type="warning" onClick={() => Toast.warning(opts)}>
+                Warning
+            </Button>
+            <br />
+            <br />
+            <Button type="danger" onClick={() => Toast.error(opts)}>
+                Error
+            </Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### 链接文本
+
+配合 Typography 可以自定义链接文本,用来配合更复杂的场景的使用。
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Typography, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const { Text } = Typography;
+
+    let opts = {
+        content: (
+            <span>
+                <Text>Hi, Bytedance dance dance</Text>
+                <Text link style={{ marginLeft: 12 }}>
+                    更多
+                </Text>
+            </span>
+        ),
+        duration: 3,
+    };
+
+    let multiLineOpts = {
+        content: (
+            <>
+                <div>Hi, Bytedance dance dance</div>
+                <div style={{ marginTop: 8 }}>
+                    <Text link>查看详情</Text>
+                    <Text link style={{ marginLeft: 20 }}>
+                        一会再看
+                    </Text>
+                </div>
+            </>
+        ),
+        duration: 3,
+    };
+
+    return (
+        <>
+            <Button onClick={() => Toast.info(opts)}>Display Toast</Button>
+            <br />
+            <br />
+            <Button onClick={() => Toast.info(multiLineOpts)}>Display Multi-line Toast</Button>
+        </>
+    );
+}
+render(Demo);
+```
+
+### 修改延时
+
+自定义时长 10s,默认时长为 3s
+
+```jsx live=true noInline=true
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    let opts = {
+        content: 'Hi, Bytedance dance dance',
+        duration: 10,
+    };
+
+    return <Button onClick={() => Toast.info(opts)}>Close After 10s</Button>;
+}
+render(Demo);
+```
+
+### 手动关闭
+
+当 `duration` 设置为 0 时,toast 不会自动关闭,此时必须通过手动关闭。
+
+```jsx live=true noInline=true hideInDSM
+import React, { useState } from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [toastId, setToastId] = useState();
+    function show() {
+        if (toastId) {
+            return;
+        }
+        let id = Toast.info(opts);
+        setToastId(id);
+    }
+    function hide() {
+        Toast.close(toastId);
+        destroy();
+    }
+    function destroy() {
+        setToastId(null);
+    }
+    let opts = {
+        content: 'Not auto close',
+        duration: 0,
+        onClose: destroy,
+    };
+    return (
+        <>
+            <Button type="primary" onClick={show}>
+                Show Toast
+            </Button>
+            <br />
+            <br />
+            <Button type="primary" onClick={hide}>
+                Hide Toast
+            </Button>
+        </>
+    );
+}
+
+render(Demo);
+```
+
+### Hooks 用法
+
+通过 Toast.useToast 创建支持读取 context 的 contextHolder。此时的 toast 会渲染在 contextHolder 所在的节点处。
+
+```jsx live=true noInline=true hideInDSM
+import React from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+const ReachableContext = React.createContext();
+
+function Demo(props = {}) {
+    const [toast, contextHolder] = Toast.useToast();
+    const config = {
+        duration: 0,
+        title: 'This is a success message',
+        content: <ReachableContext.Consumer>{name => `ReachableContext: ${name}`}</ReachableContext.Consumer>,
+    };
+
+    return (
+        <ReachableContext.Provider value="Light">
+            <div>
+                <Button
+                    onClick={() => {
+                        toast.success(config);
+                    }}
+                >
+                    Hook Toast
+                </Button>
+            </div>
+            {contextHolder}
+        </ReachableContext.Provider>
+    );
+}
+
+render(Demo);
+```
+
+如果需要渲染到 Portal 中可以使用 ReactDOM.createPortal 方法。
+
+```jsx live=true noInline=true
+import React, { useRef } from 'react';
+import { Toast, Button } from '@douyinfe/semi-ui';
+
+const ReachableContext = React.createContext();
+
+const useCreatePortalInBody = () => {
+    const wrapperRef = useRef(null);
+    if (wrapperRef.current === null && typeof document !== 'undefined') {
+        const div = document.createElement('div');
+        wrapperRef.current = div;
+    }
+    useLayoutEffect(() => {
+        const wrapper = wrapperRef.current;
+        if (!wrapper || typeof document === 'undefined') {
+            return;
+        }
+        document.querySelector('.article-wrapper').appendChild(wrapper);
+        return () => {
+            document.querySelector('.article-wrapper').appendChild(wrapper);
+        };
+    }, []);
+    return children => wrapperRef.current && ReactDOM.createPortal(children, wrapperRef.current);
+};
+
+function Demo(props = {}) {
+    const [toast, contextHolder] = Toast.useToast();
+    const createBodyPortal = useCreatePortalInBody();
+    const config = {
+        duration: 3,
+        title: 'This is a success message',
+        content: <ReachableContext.Consumer>{name => `ReachableContext: ${name}`}</ReachableContext.Consumer>,
+    };
+
+    return (
+        <ReachableContext.Provider value="Light">
+            <div>
+                <Button
+                    onClick={() => {
+                        toast.success(config);
+                    }}
+                >
+                    Hook Toast
+                </Button>
+            </div>
+            {createBodyPortal(
+                <div style={{ position: 'fixed', top: 0, left: '50%', zIndex: 10000 }}>{contextHolder}</div>
+            )}
+        </ReachableContext.Provider>
+    );
+}
+
+render(Demo);
+```
+
+## API 参考
+
+组件提供的静态方法,使用方式和参数如下:展示:可以直接传入 `options` 对象或 `string`,返回值为`toastId`:`const toastId = Toast.info({ /*...options*/ })`
+
+-   `Toast.info(options || string)`
+-   `Toast.error(options || string)`
+-   `Toast.warning(options || string)`
+-   `Toast.success(options || string)`
+
+手动关闭 ( `toastId` 为展示方法的返回值)
+
+-   `Toast.close(toastId)`
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| bottom | 弹出位置 bottom | number \| string | - | 0.25.0 |
+| content | 提示内容 | ReactNode | '' |  |
+| duration | 自动关闭的延时,单位 s,设为 0 时不自动关闭 | number | 3 |  |
+| getPopupContainer | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative` | () => HTMLElement \| null | () => document.body | 0.34.0 |
+| icon | 自定义图标 | ReactNode |  | 0.25.0 |
+| left | 弹出位置 left | number \| string | - | 0.25.0 |
+| right | 弹出位置 right | number \| string | - | 0.25.0 |
+| showClose | 是否展示关闭按钮 | boolean | true | 0.25.0 |
+| textMaxWidth | 内容的最大宽度 | number \| string | 450 | 0.25.0 |
+| theme | 填充样式,支持 `light`, `normal` | string | `normal` | 1.0.0 |
+| top | 弹出位置 top | number \| string | - | 0.25.0 |
+| zIndex | 弹层 z-index 值 | number | 1010 |  |
+| onClose | toast 关闭的回调函数 | () => void |  |  |
+
+全局配置在调用前提前配置,全局一次生效 ( >= 0.25.0 ):
+
+-   `Toast.config(config)`
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| bottom | 弹出位置 bottom | number \| string | - | 0.25.0 |
+| duration | 自动关闭的延时,单位 s,设为 0 时不自动关闭 | number | 3 | 0.25.0 |
+| getPopupContainer | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative` | () => HTMLElement \| null | () => document.body | 1.23.0 |
+| left | 弹出位置 left | number \| string | - | 0.25.0 |
+| right | 弹出位置 right | number \| string | - | 0.25.0 |
+| top | 弹出位置 top | number \| string | - | 0.25.0 |
+| zIndex | 弹层 z-index 值 | number | 1010 | 0.25.0 |
+
+-   `ToastFactory.create(config) => Toast`  
+    如果您的应用中需要使用不同 config 的 Toast,可以使用 ToastFactory.create(config)创建新的 Toast (>= 1.23):
+
+```jsx live=true noInline=true
+import React from 'react';
+function Demo() {
+    const ToastInCustomContainer = ToastFactory.create({
+        getPopupContainer: () => document.getElementById('custom-toast-container'),
+    });
+    return (
+        <div>
+            <Button onClick={() => Toast.info('Toast')}>Default Toast</Button>
+            <br />
+            <br />
+            <Button onClick={() => ToastInCustomContainer.info('Toast in some container')}>
+                Toast in custom container
+            </Button>
+            <div id="custom-toast-container">custom container</div>
+        </div>
+    );
+}
+render(Demo);
+```
+
+全局销毁 ( >= 0.25.0 ):
+
+-   `Toast.destroyAll()`
+
+HookToast ( >= 1.2.0 ):
+
+-   `Toast.useToast()`  
+    当你需要使用 Context 时,可以通过 Toast.useToast 创建一个 contextHolder 插入相应的节点中。此时通过 hooks 创建的 Toast 将会得到 contextHolder 所在位置的所有上下文。创建的 toast 对象拥有与以下方法:`info`, `success`, `warning`, `error`, `close`。
+
+## 设计变量
+
+<DesignToken/>

+ 395 - 0
content/input/autocomplete/index-en-US.md

@@ -0,0 +1,395 @@
+---
+localeCode: en-US
+order: 15
+category: Input
+title: AutoComplete
+icon: doc-autocomplete
+brief: The input box is automatically filled.
+---
+
+## When to use
+
+Used to provide input suggestions to the input box and perform automatic completion operations
+
+The difference with the searchable Select component:
+- AutoComplete is essentially an enhanced Input component that provides input suggestions, while Select is a selector
+- When you click to expand, Select will clear all the values in the input box, and AutoComplete will keep the last selected value
+- Select's selected item rendering (renderSelectedItem) can be more customized and can be any type of ReactNode, while AutoComplete only allows strings
+
+## Demos
+
+### How to import
+
+```jsx import
+import { AutoComplete } from '@douyinfe/semi-ui';
+```
+
+### Basic usage
+
+Monitor user input through onSearch, pass input suggestions through data, and maintain control through onChange. OnChange is triggered when the input box changes/selects an input item
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+() => {
+    const [stringData, setStringData] = useState([]);
+    const [value, setValue] = useState('');
+    const handleStringSearch = (value) => {
+        let result;
+        if (value) {
+            result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
+        } else {
+            result = [];
+        }
+        setStringData(result);
+    }
+
+    const handleChange = (value) => {
+        console.log('onChange', value);
+        setValue(value);
+    }
+    return (
+        <AutoComplete
+            data={stringData}
+            value={value}
+            showClear
+            prefix={<IconSearch />}
+            placeholder="Search... "
+            onSearch={handleStringSearch}
+            onChange={handleChange}
+            style={{ width: 200 }}
+        />
+    )
+}
+```
+
+### Custom option rendering
+
+When you need to customize the rendering of candidates, data can be passed in an array of objects (each Object must contain two keys, label and value, value is the value selected by the candidate, and label is the content displayed by the candidate)
+The rendering of candidates can be customized through renderItem
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete, Avatar } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class CustomOptionDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            data: [],
+            color: ['amber', 'indigo', 'cyan'],
+            list: [
+                { name: 'Xia', email: '[email protected]', abbr: 'XK', color: 'amber' },
+                { name: 'Shen', email: '[email protected]', abbr: 'SY', color: 'indigo' },
+                { name: 'Qu', email: '[email protected]', abbr: 'CY', color: 'blue' },
+                { name: 'Wen', email: '[email protected]', abbr: 'JM', color: 'cyan' },
+            ],
+        };
+    }
+
+    search(value) {
+        let result;
+        if (value) {
+            result = this.state.list.map(item => {
+                return { ...item, value: item.name, label: item.email };
+            });
+        } else {
+            result = [];
+        }
+        this.setState({ data: result });
+    }
+
+    renderOption(item) {
+        let optionStyle = {
+            display: 'flex',
+        };
+        return (
+            <>
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div style={{ marginLeft: 4 }}>
+                    <div style={{ fontSize: 14, marginLeft: 4 }}>{item.name}</div>
+                    <div style={{ marginLeft: 4 }}>{item.email}</div>
+                </div>
+            </>
+        );
+    }
+
+    render() {
+        return (
+            <AutoComplete
+                data={this.state.data}
+                prefix={<IconSearch />}
+                style={{ width: '250px' }}
+                renderSelectedItem={option => option.email}
+                renderItem={this.renderOption}
+                onSearch={this.search.bind(this)}
+                onSelect={v => console.log(v)}
+            ></AutoComplete>
+        );
+    }
+}
+```
+
+### Remote search
+
+Get user input value from onSearch, update data value dynamically, update loading
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class ObjectDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            list: [
+                { value: 'tiktok', label: 'douyin', email: '[email protected]', type: 2 },
+                { value: 'hotsoon', label: 'huoshan', email: '[email protected]', type: 3 },
+                { value: 'pipixia', label: 'pip', email: '[email protected]' },
+            ],
+            loading: false,
+        };
+        this.onSearch = this.onSearch.bind(this);
+        this.handleSelect = this.handleSelect.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+        this.renderSelectedItem = this.renderSelectedItem.bind(this);
+        this.search = debounce(this.search.bind(this), 200);
+    }
+
+    onSearch(inputValue) {
+        this.setState({ loading: true });
+        this.search(inputValue);
+    }
+
+    search(inputValue) {
+        let { list } = this.state;
+        const newList = list.map(item => {
+            let num = Math.random()
+                .toString()
+                .slice(2, 5);
+            let option = inputValue + '-' + num;
+            return { ...item, label: 'Name:' + option, value: option };
+        });
+        this.setState({ list: newList, loading: false });
+    }
+
+    handleSelect(value) {
+        console.log(value);
+    }
+
+    renderItem(item) {
+        return (
+            <div>
+                <div>{item.label}</div>
+                <div>email: {item.email}</div>
+                <div style={{ color: 'pink' }}>value: {item.value}</div>
+            </div>
+        );
+    }
+
+    renderSelectedItem(item) {
+        // Note: Unlike Select, only String type values can be returned here, ReactNode cannot be returned
+        return item.value;
+    }
+
+    render() {
+        const { loading } = this.state;
+        return (
+            <div>
+                <AutoComplete
+                    data={this.state.list}
+                    style={{ width: 250 }}
+                    prefix={<IconSearch />}
+                    onSearch={this.onSearch}
+                    loading={loading}
+                    onChangeWithObject
+                    renderItem={this.renderItem}
+                    renderSelectedItem={this.renderSelectedItem}
+                    onSelect={this.handleSelect}
+                ></AutoComplete>
+            </div>
+        );
+    }
+}
+```
+
+### Size
+
+The size of the input box can be set by setting size, optional `small`, `default` (default), `large`
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="small"
+            placeholder={'small'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="default"
+            placeholder={'default'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="large"
+            placeholder={'large'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+    </div>
+)
+```
+
+### The position of the drop-down menu
+
+The position of the drop-down menu can be set by setting position, and the optional values refer to Tooltip position
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            position="top"
+            placeholder="The options menu is shown at the top"
+            style={{ width: 200, margin: 10 }}
+        ></AutoComplete>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            position="rightTop"
+            placeholder="The options menu is shown on the right"
+            style={{ width: 200, margin: 10 }}
+        ></AutoComplete>
+    </div>
+)
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <AutoComplete data={[1, 2, 3, 4]} placeholder={'Disable drop-down menu'} disabled style={{ width: 200 }}></AutoComplete>
+)
+```
+
+### Validate status
+
+Different verification states can be set to show different styles
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <AutoComplete defaultValue="ies" validateStatus="warning"></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete defaultValue="ies" validateStatus="error"></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete defaultValue="ies"></AutoComplete>
+    </>
+)
+```
+
+### Custom empty content
+
+Can set up custom display empty content
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete, Empty } from '@douyinfe/semi-ui';
+import { IllustrationNoContent } from '@douyinfe/semi-illustrations';
+
+() => {
+    let [data, setData] = useState([]);
+    const [loading, setLoading] = useState(false);
+
+    const fetchData = v => {
+        setLoading(true);
+        setTimeout(() => {
+            if (!v) {
+                setData([]);
+                setLoading(false);
+                return;
+            }
+            setData(() => {
+                const res = Array.from(Array(5)).map(c => Math.random());
+                return res;
+            });
+            setLoading(false);
+        }, 1000);
+    };
+
+    return (
+        <AutoComplete
+            loading={loading}
+            data={data}
+            emptyContent={<Empty style={{ padding: 12, width: 300 }} image={<IllustrationNoContent style={{width: 150, height: 150}}/>} description={'no content yet'} />}
+            onSearch={fetchData}
+        />
+    );
+};
+```
+
+## API reference
+
+| Properties | Instructions | Type | Default | Version|
+| --- | --- | --- | --- | -- |
+| autoFocus | Whether to auto focus | bool | false | 1.16.0|
+| autoAdjustOverflow | Whether to automatically adjust the direction when the floating layer is blocked<br/>| bool | true | 0.27.0|
+| className | Style class name | string | |
+| data | The data source of the candidates, which can be a string array or an object array | array | [] |
+| defaultActiveFirstOption | Whether to highlight the first option by default (press enter to select directly) | bool | false |
+| defaultOpen | Whether to expand the drop-down menu by default | boolean | false |
+| defaultValue | Defaults | string | |
+| disabled | Whether to disable | boolean | false |
+| dropdownClassName | Css class name of the drop-down list | string |  |
+| dropdownStyle | Inline style of the drop-down list | object |  |
+| emptyContent | Customize the drop-down content when data is empty | ReactNode | null | 1.16.0|
+| getPopupContainer | Specify the parent DOM, the floating layer of the drop-down list will be rendered into the DOM, and the customization needs to set `position: relative` | () => HTMLElement | () => document.body |
+| loading | Whether the drop-down list shows loading animation | boolean | false |
+| maxHeight | The maximum height of the drop-down list | number\|string | 300 |
+| motion | Is there an animation when the drop-down list appears/hidden | boolean\|object | true |
+| onSelectWithObject | When clicking on the candidate, whether to add other attributes of the selected item option as callback parameters. When set to true, the input parameter type of onSelect will change from `string` to object: {value, label, ...rest} | boolean | false | 1.23.0|
+| placeholder | Input box prompt | string | |
+| position | The display position of the drop-down menu, the optional values are the same as the tooltip component | string | 'bottomLeft' |
+| prefix | The prefix tag of the select box | ReactNode |  | 0.23.0|
+| renderItem | Control the rendering of drop-down list candidates | (option: string\|Item)=> React.Node |  |
+| renderSelectedItem | Customize the drop-down list through renderSelectedItem after the candidate is clicked and selected, the content rendered in the select box<br/>** only supports the return value of String type **| (option: string\|Item) => string |  | 0.23.0|
+| showClear | Whether to show the clear button | boolean | false |
+| size | Size, optional `small`, `default`, `large`  | string | `default` |
+| style | style | object |  |
+| suffix | The prefix tag of the select box | ReactNode |  | 0.23.0|
+| value | The current value | string\|number |  |
+| validateStatus | Validation status, optional values are `default`, `error`, `warning`, and the default is default. Only affect the display style | string | 'default' | 1.14.0|
+| zIndex | ZIndex of the drop-down menu | number |  |
+| onBlur | Callback when the focus is lost | Function(event) | |
+| onChange | Input box change / change when the candidate is selected | Function(value:string\|number) | | 1.23.0|
+| onFocus | The callback when the focus is obtained | Function(event) | |
+| onSearch | Callback when input changes | Function(value: string) | |
+| onSelect | Callback when the drop-down menu candidate is selected | Function(item: string\|number\|Item) | |
+
+## Design Token
+<DesignToken/>

+ 396 - 0
content/input/autocomplete/index.md

@@ -0,0 +1,396 @@
+---
+localeCode: zh-CN
+order: 15
+category: 输入类
+title: AutoComplete 自动完成
+icon: doc-autocomplete
+brief: 输入框自动填充。
+---
+
+## 何时使用
+
+用于对输入框提供输入建议,进行自动补全的操作
+
+
+与可搜索的 Select 组件的区别:
+- AutoComplete 本质上是一个增强型的提供了输入建议的 Input 组件,而 Select 是一个选择器
+- 点击展开时,Select 会将输入框的值全部清空,而 AutoComplete 会保留上次选中的值
+- Select 的已选项渲染(renderSelectedItem)可定制化程度更高,可以为任意类型的 ReactNode,而 AutoComplete 只允许为字符串
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { AutoComplete } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+通过 onSearch 监听用户输入,将输入建议通过 data 传入,通过 onChange 保持受控,当输入框变化/选中输入项时会触发 onChange
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+() => {
+    const [stringData, setStringData] = useState([]);
+    const [value, setValue] = useState('');
+    const handleStringSearch = (value) => {
+        let result;
+        if (value) {
+            result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
+        } else {
+            result = [];
+        }
+        setStringData(result);
+    }
+
+    const handleChange = (value) => {
+        console.log('onChange', value);
+        setValue(value);
+    }
+    return (
+        <AutoComplete
+            data={stringData}
+            value={value}
+            showClear
+            prefix={<IconSearch />}
+            placeholder="搜索... "
+            onSearch={handleStringSearch}
+            onChange={handleChange}
+            style={{ width: 200 }}
+        />
+    )
+}
+```
+
+### 自定义候选项渲染
+
+需要自定义候选项渲染时,data 可以传入一个对象数组(每个 Object 必须含有 label、value 两个 key,value 为候选项选中的值,label 为候选项展示的内容)  
+通过 renderItem 可以自定义候选项的渲染
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete, Avatar } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class CustomOptionDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            data: [],
+            color: ['amber', 'indigo', 'cyan'],
+            list: [
+                { name: '夏可漫', email: '[email protected]', abbr: 'XK', color: 'amber' },
+                { name: '申悦', email: '[email protected]', abbr: 'SY', color: 'indigo' },
+                { name: '曲晨一', email: '[email protected]', abbr: 'CY', color: 'blue' },
+                { name: '文嘉茂', email: '[email protected]', abbr: 'JM', color: 'cyan' },
+            ],
+        };
+    }
+
+    search(value) {
+        let result;
+        if (value) {
+            result = this.state.list.map(item => {
+                return { ...item, value: item.name, label: item.email };
+            });
+        } else {
+            result = [];
+        }
+        this.setState({ data: result });
+    }
+
+    renderOption(item) {
+        let optionStyle = {
+            display: 'flex',
+        };
+        return (
+            <>
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div style={{ marginLeft: 4 }}>
+                    <div style={{ fontSize: 14, marginLeft: 4 }}>{item.name}</div>
+                    <div style={{ marginLeft: 4 }}>{item.email}</div>
+                </div>
+            </>
+        );
+    }
+
+    render() {
+        return (
+            <AutoComplete
+                data={this.state.data}
+                prefix={<IconSearch />}
+                style={{ width: '250px' }}
+                renderSelectedItem={option => option.email}
+                renderItem={this.renderOption}
+                onSearch={this.search.bind(this)}
+                onSelect={v => console.log(v)}
+            ></AutoComplete>
+        );
+    }
+}
+```
+
+### 远程搜索
+
+从 onSearch 中获取用户输入值,动态更新 data 值,更新 loading
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class ObjectDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            list: [
+                { value: 'tiktok', label: 'douyin', email: '[email protected]', type: 2 },
+                { value: 'hotsoon', label: 'huoshan', email: '[email protected]', type: 3 },
+                { value: 'pipixia', label: 'pip', email: '[email protected]' },
+            ],
+            loading: false,
+        };
+        this.onSearch = this.onSearch.bind(this);
+        this.handleSelect = this.handleSelect.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+        this.renderSelectedItem = this.renderSelectedItem.bind(this);
+        this.search = debounce(this.search.bind(this), 200);
+    }
+
+    onSearch(inputValue) {
+        this.setState({ loading: true });
+        this.search(inputValue);
+    }
+
+    search(inputValue) {
+        let { list } = this.state;
+        const newList = list.map(item => {
+            let num = Math.random()
+                .toString()
+                .slice(2, 5);
+            let option = inputValue + '-' + num;
+            return { ...item, label: '名称:' + option, value: option };
+        });
+        this.setState({ list: newList, loading: false });
+    }
+
+    handleSelect(value) {
+        console.log(value);
+    }
+
+    renderItem(item) {
+        return (
+            <div>
+                <div>{item.label}</div>
+                <div>email: {item.email}</div>
+                <div style={{ color: 'pink' }}>value: {item.value}</div>
+            </div>
+        );
+    }
+
+    renderSelectedItem(item) {
+        // 注意:与Select不同,此处只能返回String类型的值,不能返回ReactNode
+        return item.value;
+    }
+
+    render() {
+        const { loading } = this.state;
+        return (
+            <div>
+                <AutoComplete
+                    data={this.state.list}
+                    style={{ width: 250 }}
+                    prefix={<IconSearch />}
+                    onSearch={this.onSearch}
+                    loading={loading}
+                    onChangeWithObject
+                    renderItem={this.renderItem}
+                    renderSelectedItem={this.renderSelectedItem}
+                    onSelect={this.handleSelect}
+                ></AutoComplete>
+            </div>
+        );
+    }
+}
+```
+
+### 尺寸
+
+通过设置 size 可设置输入框尺寸,可选`small`,`default`(默认),`large`
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="small"
+            placeholder={'small'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="default"
+            placeholder={'default'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            size="large"
+            placeholder={'large'}
+            style={{ width: 200 }}
+        ></AutoComplete>
+    </div>
+)
+```
+
+### 下拉菜单的位置
+
+通过设置 position 可设置下拉菜单位置,可选值参考 Tooltip position
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            position="top"
+            placeholder="选项菜单在上方显示"
+            style={{ width: 200, margin: 10 }}
+        ></AutoComplete>
+        <AutoComplete
+            data={[1, 2, 3, 4]}
+            position="rightTop"
+            placeholder="选项菜单在右侧显示"
+            style={{ width: 200, margin: 10 }}
+        ></AutoComplete>
+    </div>
+)
+```
+
+### 禁用
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <AutoComplete data={[1, 2, 3, 4]} placeholder={'禁用下拉菜单'} disabled style={{ width: 200 }}></AutoComplete>
+)
+```
+
+### 校验状态
+
+可设置不同校验状态,展示不同样式
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <AutoComplete defaultValue="ies" validateStatus="warning"></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete defaultValue="ies" validateStatus="error"></AutoComplete>
+        <br />
+        <br />
+        <AutoComplete defaultValue="ies"></AutoComplete>
+    </>
+)
+```
+
+### 自定义空内容
+
+可设置自定义展示空内容
+
+```jsx live=true
+import React from 'react';
+import { AutoComplete, Empty } from '@douyinfe/semi-ui';
+import { IllustrationNoContent } from '@douyinfe/semi-illustrations';
+
+() => {
+    let [data, setData] = useState([]);
+    const [loading, setLoading] = useState(false);
+
+    const fetchData = v => {
+        setLoading(true);
+        setTimeout(() => {
+            if (!v) {
+                setData([]);
+                setLoading(false);
+                return;
+            }
+            setData(() => {
+                const res = Array.from(Array(5)).map(c => Math.random());
+                return res;
+            });
+            setLoading(false);
+        }, 1000);
+    };
+
+    return (
+        <AutoComplete
+            loading={loading}
+            data={data}
+            emptyContent={<Empty style={{ padding: 12, width: 300 }} image={<IllustrationNoContent style={{width: 150, height: 150}}/>} description={'暂无内容'} />}
+            onSearch={fetchData}
+        />
+    );
+};
+```
+
+## API 参考
+
+| 属性 | 说明 | 类型 | 默认值 | 版本|
+| --- | --- | --- | --- |--- |
+| autoFocus | 是否自动聚焦 | bool | false | 1.16.0|
+| autoAdjustOverflow | 浮层被遮挡时是否自动调整方向 | bool | true | 0.27.0|
+| className | 样式类名 | string | |
+| data | 候选项的数据源,可以为字符串数组或对象数组 | array | [] |
+| defaultActiveFirstOption | 是否默认高亮第一个选项(按回车可直接选中) | bool | false |
+| defaultOpen | 是否默认展开下拉菜单 | boolean | false |
+| defaultValue | 默认值 | string | |
+| disabled | 是否禁用 | boolean | false |
+| dropdownClassName | 下拉列表的 css 类名 | string |  |
+| dropdownStyle | 下拉列表的内联样式 | object |  |
+| emptyContent | data 为空时自定义下拉内容  | ReactNode | null | 1.16.0 |
+| getPopupContainer | 指定父级 DOM,下拉列表浮层将会渲染至该 DOM 中,自定义需要设置 `position: relative` | () => HTMLElement | () => document.body |
+| loading | 下拉列表是否展示加载动画 | boolean | false |
+| maxHeight | 下拉列表的最大高度 | number\|string | 300 |
+| motion | 下拉列表出现/隐藏时,是否有动画 | boolean\|object | true |
+| onSelectWithObject | 点击候选项时,是否将选中项 option 的其他属性也作为回调入参。设为 true 时,onSelect 的入参类型会从 `string` 变为 object: { value, label, ...rest }| boolean | false |1.23.0 |
+| placeholder | 输入框提示 | string | |
+| position | 下拉菜单的显示位置,可选值同 tooltip 组件 | string | 'bottomLeft' |
+| prefix | 选择框的前缀标签 | ReactNode |  | 0.23.0|
+| renderItem | 控制下拉列表候选项的渲染 | (option: string\|Item)=> React.Node |  |
+| renderSelectedItem | 通过 renderSelectedItem 自定义下拉列表候选项被点击选中后,在选择框中的渲染内容<br/>**仅支持 String 类型的返回值**<br/> | (option: string\|Item) => string |  |0.23.0 |
+| showClear | 是否展示清除按钮 | boolean | false |
+| size | 尺寸,可选`small`, `default`, `large`  | string | `default` |
+| style | 样式 | object |  |
+| suffix | 选择框的前缀标签 | ReactNode |  |0.23.0 |
+| validateStatus | 校验状态,可选值`default`、`error`、`warning`,默认 default。仅影响展示样式 | string | 'default' | 1.14.0|
+| value | 当前值 | string\|number | 无 |
+| zIndex | 下拉菜单的 zIndex | number |  |
+| onBlur | 失去焦点时的回调 | Function(event) | |
+| onChange | 输入框变化/候选项选中时变化 | Function(value:string\|number) | |1.23.0 |
+| onFocus | 获得焦点时的回调 | Function(event) | |
+| onSearch | 输入变化时的回调 | Function(value: string) | |
+| onSelect | 下拉菜单候选项被选中时的回调 | Function(item: string\|number\|Item) | |
+
+## 设计变量
+<DesignToken/>

+ 532 - 0
content/input/button/index-en-US.md

@@ -0,0 +1,532 @@
+---
+localeCode: en-US
+order: 16
+category: Input
+title:  Button
+subTitle: Button
+icon: doc-button
+dir: column
+brief: Users use buttons to trigger an operation or jump.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { Button, SplitButtonGroup } from '@douyinfe/semi-ui';
+```
+
+### Button Type
+
+Buttons support the following types:
+
+-   Primary button ("primary", default)
+-   Secondary button ("secondary")
+-   Tertiary button ("tertiary")
+-   Warning button ("warning")
+-   Danger button ("danger")
+
+> Primary and Secondary button have the same colors in Semi's default theme, but you can implement different Primary and Secondary colors by customizing the theme.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div className="btn-margin-right">
+      <Button>Primary Button</Button>
+      <Button type="secondary">Secondary Button</Button>
+      <Button type="tertiary">Tertiary Button</Button>
+      <Button type="warning">Warning Button</Button>
+      <Button type="danger">Danger Button</Button>
+    </div>
+  );
+}
+
+```
+
+#### About the Font Color
+
+[CSS Variables](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties) are used with the button:
+
+-   `var(--semi-color-primary)`: main
+-   `var(--semi-color-secondary)`: secondary
+-   `var(--semi-color-colored)`: third
+-   `var(--semi-color-warning)`: warning
+-   `var(--semi-color-danger)`: danger
+
+You can define your elements directly using these theme colors.
+
+```jsx live=true dir="column"
+import React from 'react';
+
+function ButtonDemo() {
+  const types = [['primary', 'primary'], ['secondary', 'secondary'], ['tertiary', 'tertiary'], ['warning', 'warning'], ['danger', 'danger']];
+
+  return (
+    <article>
+      {types.map((type, index) => (
+        <strong key={index} style={{ color: `var(--semi-color-${Array.isArray(type) ? type[0] : type})`, marginRight: 10 }}>{Array.isArray(type) ? type[1]: type}</strong>
+      ))}
+    </article>
+  );
+}
+```
+
+### Button Theme
+
+The themes currently available are:
+
+-   `light`: light background
+-   `solid`: dark background
+-   `borderless`: no background
+
+The default theme is `light`
+
+#### Light Background
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const themes = [['light', 'light']];
+  const types = [['primary', 'primary'], ['secondary', 'secondary'], ['tertiary', 'tertiary'], ['warning', 'warning'], ['danger', 'danger']];
+
+  return (
+    <div>{
+      themes.map((theme, idxTheme) => (
+        <div key={idxTheme}>
+          <ul style={{ listStyle: 'none', display: 'flex', margin: 0, padding: 0 }}>
+            {types.map((type, idxType) => (
+              <li key={'' + idxTheme + idxType} style={{margin:10}}>
+                <Button
+                  theme={theme[0]}
+                  type={type[0]}
+                >
+                  {theme[1]} {type[1]}
+                </Button>
+              </li>)
+            )}
+           </ul>
+        </div>))
+    }
+    </div>
+  );
+}
+```
+
+#### Dark Background
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const themes = [['solid', 'solid']];
+  const types = [['primary', 'primary'], ['secondary', 'secondary'], ['tertiary', 'tertiary'], ['warning', 'warning'], ['danger', 'danger']];
+
+  return (
+    <div>{
+      themes.map((theme, idxTheme) => (
+        <div key={idxTheme}>
+          <ul style={{ listStyle: 'none', display: 'flex', margin: 0, padding: 0 }}>
+            {types.map((type, idxType) => (
+              <li key={'' + idxTheme + idxType} style={{margin:10}}>
+                <Button
+                  theme={theme[0]}
+                  type={type[0]}
+                >
+                  {theme[1]} {type[1]}
+                </Button>
+              </li>)
+            )}
+           </ul>
+        </div>))
+    }
+    </div>
+  );
+}
+```
+
+#### No Background
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const themes = [['borderless', 'borderless']];
+  const types = [['primary', 'primary'], ['secondary', 'secondary'], ['tertiary', 'tertiary'], ['warning', 'warning'], ['danger', 'danger']];
+
+  return (
+    <div>{
+      themes.map((theme, idxTheme) => (
+        <div key={idxTheme}>
+          <ul style={{ listStyle: 'none', display: 'flex', margin: 0, padding: 0 }}>
+            {types.map((type, idxType) => (
+              <li key={'' + idxTheme + idxType} style={{margin:10}}>
+                <Button
+                  theme={theme[0]}
+                  type={type[0]}
+                >
+                  {theme[1]} {type[1]}
+                </Button>
+              </li>)
+            )}
+           </ul>
+        </div>))
+    }
+    </div>
+  );
+}
+```
+
+### Size
+
+Three sizes are defined by default:
+
+-   Big: "Large"
+-   Default: "default."
+-   Small: "Small"
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button size='large' style={{marginRight:8}}>large</Button>
+      <Button size='default' style={{marginRight:8}}>default</Button>
+      <Button size='small'>small</Button>
+    </div>
+  );
+}
+```
+
+### Block Button
+
+The block button has a predefined width, and its width is independent of the width of the contents of the button.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button block>block button</Button>
+    </div>
+  );
+}
+```
+
+### Icon Button
+
+An icon that defines a button.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+import { IconCamera, IconSidebar, IconChevronDown } from '@douyinfe/semi-icons';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <strong>Default Status:</strong>
+      <Button icon={<IconCamera />}/>
+          <br/><br/>
+      <strong>Disabled Status:</strong>
+      <Button icon={<IconCamera />}/>
+          <br/><br/>
+      <strong>With Type:</strong>
+      <span className="btn-margin-right">
+      <Button type="primary" icon={<IconCamera />}/>
+      <Button type="secondary" icon={<IconCamera />}/>
+      <Button type="warning" icon={<IconCamera />}/>
+      <Button type="danger" icon={<IconCamera />}/>
+      </span>
+          <br/><br/>
+      <strong>Change Theme:</strong>
+      <Button icon={<IconCamera />} theme="solid" style={{ marginRight: 10 }}/>
+      <Button icon={<IconCamera />} theme="light"/>
+          <br/><br/>
+      <strong>Change Icon Position:</strong>
+      <Button icon={<IconSidebar />} theme="solid" style={{ marginRight: 10 }}>Collpase</Button>
+      <Button icon={<IconChevronDown />} theme="solid" iconPosition={"right"}>Expand Options</Button>
+          <br/><br/>
+    </div>
+  );
+}
+```
+
+### Link Button
+
+We recommend using Typography to achieve link text button. Refer to [Typography](/en-US/basic/typography) for more information.
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+import { IconLink } from '@douyinfe/semi-icons';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+      <Text link={{ href: 'https://semi.design/' }}>Link</Text>
+      <br />
+      <br />
+      <Text link={{ href: 'https://semi.design/' }}>Open Website</Text>
+      <br />
+      <br />
+      <Text link icon={<IconLink />} underline>Link</Text>
+    </div>
+  )
+}
+```
+
+### Prohibited Status
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button disabled>Disabled</Button>
+      <Button disabled theme="borderless">No background and disabled</Button>
+      <Button disabled theme="light">Light and disbaled</Button>
+      <Button disabled theme="borderless" type="primary">No background, primary and disabled</Button>
+      <Button disabled theme="solid" type="warning">Solid, warning and disabled</Button>
+    </div>
+  );
+}
+```
+
+### Loading State
+
+The button supports the Loading state, by setting the loading parameter value to true, note: the state priority is higher than the loading state.
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const [saveLoading, setSaveLoading] = useState(false);
+  const [delLoading, setDelLoading] = useState(true);
+  const [repLoading, setRepLoading] = useState(true);
+
+  const reset = status => {
+    status = !!status;
+    setSaveLoading(status);
+    setDelLoading(status);
+    setRepLoading(status);
+  };
+
+  return (
+    <div>
+      <div>
+        <div className="btn-margin-right" style={{ display: 'inline-flex', alignItems: 'center', paddingBottom: 14 }}>
+          <Button onClick={() => reset(false)}>Stop loading</Button>
+          <Button onClick={() => reset(true)}>Start loading</Button>
+        </div>
+      </div>
+      <hr/>
+      <Button loading={saveLoading} onClick={() => setSaveLoading(true)} style={{ marginRight: 14 }}>Save</Button>
+      <Button loading={delLoading} icon={<IconDelete />} type="danger" onClick={() => setDelLoading(true)} style={{ marginRight: 14 }}>Delete</Button>
+      <div style={{ width: 200, display: 'inline-block'}}>
+        <Button loading={repLoading} type="warning" block theme="solid" onClick={() => setRepLoading(true)}>Revoke</Button>
+      </div>
+    </div>
+  );
+}
+```
+
+### Button Combination
+
+You can put multiple buttons in `ButtonGroup` In the container, by setting `size`, `disabled`, `type` You can uniformly set the button size in the button combination, whether disabled and type.
+
+#### Combined Dimensions
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button, ButtonGroup } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const sizes = ['large', 'default', 'small'];
+
+  return (
+  <div style={{ display: 'flex' }}>
+    {sizes.map(size => (
+      <div style={{ marginRight: 10 }} key={size}>
+        <ButtonGroup size={size}>
+          <Button>Copy</Button>
+          <Button>Search</Button>
+          <Button>Cut</Button>
+        </ButtonGroup>
+      </div>
+    ))}
+  </div>
+  );
+}
+```
+
+#### Combined Disabled
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button, ButtonGroup } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+  <div style={{ display: 'flex' }}>
+    <div style={{ marginRight: 10 }}>
+      <ButtonGroup disabled>
+        <Button>Copy</Button>
+        <Button>Search</Button>
+        <Button>Cut</Button>
+      </ButtonGroup>
+    </div>
+  </div>
+  );
+}
+```
+
+#### Combined Type
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button, ButtonGroup } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const types = ['primary', 'secondary', 'tertiary', 'warning', 'danger'];
+
+  return (
+  <div style={{ display: 'flex' }}>
+    {types.map(type => (
+      <div style={{ marginRight: 10 }} key={type}>
+        <ButtonGroup type={type}>
+          <Button>Copy</Button>
+          <Button>Search</Button>
+          <Button>Cut</Button>
+        </ButtonGroup>
+      </div>
+    ))}
+  </div>
+  );
+}
+```
+
+### Split Button Group
+
+**V1.12.0**
+
+In the scene where `Button` and `Dropdown` are combined, split buttons can be used. The split buttons add the space between the buttons and change the rounded corners of the buttons.
+
+#### Basic Usage
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { SplitButtonGroup, Dropdown, Button } from '@douyinfe/semi-ui';
+import { IconTreeTriangleDown } from '@douyinfe/semi-icons';
+
+function SplitButtonDemo(){
+
+  const menu = [
+    { node: 'title', name: 'Title' },
+    { node: 'item', name: 'Edit', onClick: () => console.log('Edit clicked') },
+    { node: 'item', name: 'Reset', type: 'secondary' },
+    { node: 'divider' },
+    { node: 'item', name: 'Create', type: 'tertiary' },
+    { node: 'item', name: 'Copy', type: 'warning' },
+    { node: 'divider' },
+    { node: 'item', name: 'Delete', type: 'danger' },
+  ];
+
+  const [btnVisible,setBtnVisible] = useState({
+    1:false,
+    2:false,
+    3:false
+  })
+
+  const handleVisibleChange = (key,visible)=>{
+    newBtnVisible = {...btnVisible};
+    newBtnVisible[key] = visible;
+    setBtnVisible(newBtnVisible)
+  }
+
+  return (
+    <div>
+      <SplitButtonGroup style={{marginRight:10}}>
+        <Button theme="solid" type="primary">SplitButton</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(1,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[1]?{background:'var(--semi-color-primary-hover)',padding:'8px 4px'}:{padding:'8px 4px'}} theme="solid" type="primary" icon={<IconTreeTriangleDown size="small" />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+      <SplitButtonGroup style={{marginRight:10}}>
+        <Button theme="light" type="primary">SplitButton</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(2,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[2]?{background:'var(--semi-color-fill-1)',padding:'8px 4px'}:{padding:'8px 4px'}}  theme="light" type="primary" icon={<IconTreeTriangleDown size="small" />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+      <SplitButtonGroup>
+        <Button style={btnVisible[3]?{background:'var(--semi-color-fill-0)'}:null} theme="borderless" type="primary">SplitButton</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(3,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[3]?{background:'var(--semi-color-fill-1)',padding:'8px 4px'}:{padding:'8px 4px'}}  theme="borderless" type="primary" icon={<IconTreeTriangleDown size="small" />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+    </div>
+  )
+}
+```
+
+## API Reference
+
+### Button
+
+| Properties          | Instructions                                                                                                                                      | Type                             | Default   |
+| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | --------- |
+| block               | Set the button to the block level button                                                                                                          | boolean                          | false     |
+| className           | Class name                                                                                                                                        | string                           |           |
+| disabled            | Prohibited status                                                                                                                                 | boolean                          | false     |
+| htmlType           | Set the `button` native `type` value, optional values: `"button"`, `"reset"`, `"submit"`                                                          | string                           | "button"  |
+| icon                | Icon                                                                                                                                              | ReactNode              |           |
+| iconPosition        | Icon location, optional value: `"left"`\|`"right"`                                                                                                | string                           | `"left"`  |
+| loading             | Loading state                                                                                                                                     | boolean                          | false     |
+| noHorizontalPadding | Set whether to remove the inner margin in the horizontal direction, only valid for iconButton, optional: `true` (equivalent to \["left", "right"\]), "left", "right", \["left", "right"\] | boolean\|string\| Array<string\> | false     |
+| size                | Button size, optional value: `"large"`,`"default"`,`"small"`                                                                                      | string                           | "default" |
+| style               | Custom style                                                                                                                                      | CSSProperties                           |           |
+| theme               | Button theme, optional value: `"solid"` (with background color), `"borderless"` (no background color), `"light"` (light background color)         | string                           | "light"   |
+| type                | Type, optional values: `"primary"`,`"secondary"`, `"late"`, `"warning"`, `"danger"`                                                               | string                           | "primary" |
+| onClick             | Click event                                                                                                                                       | Function(MouseEvent)                         |           |
+| onMouseDown             | Mouse down                                                                                                   | Function(MouseEvent)                        |           |
+| onMouseEnter             | Mouse Enter                                                                                                   | Function(MouseEvent)                        |           |
+| onMouseLeave             | Mouse Leave                                                                                                   | Function(MouseEvent)                        |           |
+
+
+### ButtonGroup
+
+| Properties | Instructions                                                                            | Type    | Default   |
+| ---------- | --------------------------------------------------------------------------------------- | ------- | --------- |
+| disabled   | Disabled status                                                                         | boolean | false     |
+| size       | Button size, optional value: `"large"`,`"default"`,`"small"`                            | string  | "default" |
+| type       | Type, optional values: `"primary"`,`"secondary"`, `"tertiary"`, `"warning"`, `"danger"` | string  | "primary" |
+
+### SplitButtonGroup **V1.12.0**
+| Properties   | Instructions                                                            | Type      | Default     |
+| -----------  | --------------------------------------------------------------  | -------- | --------- |
+| style     | Custom style                                  | CSSProperties   |        |
+| className     | Custom class name                                  | string   |        |
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+```material
+5
+``` -->

+ 495 - 0
content/input/button/index.md

@@ -0,0 +1,495 @@
+---
+localeCode: zh-CN
+order: 16
+category: 输入类
+title:  Button 按钮
+icon: doc-button
+dir: column
+brief: 用户使用按钮来触发一个操作或者进行跳转。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Button, SplitButtonGroup } from '@douyinfe/semi-ui';
+```
+
+### 按钮类型
+
+按钮支持以下类型:
+
+-   主按钮("primary",默认)
+-   次要按钮("secondary")
+-   第三按钮("tertiary")
+-   警告按钮("warning")
+-   危险按钮("danger")
+
+> Semi 默认主题的 Primary 与 Secondary 颜色相同,但你可以通过自定义主题来实现不同的 Primary 与 Secondary 颜色。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div className="btn-margin-right">
+      <Button>主要按钮</Button>
+      <Button type="secondary">次要按钮</Button>
+      <Button type="tertiary">第三按钮</Button>
+      <Button type="warning">警告按钮</Button>
+      <Button type="danger">危险按钮</Button>
+    </div>
+  );
+}
+
+```
+
+#### 关于类型字体色值
+
+按钮的字体色值使用的都是 [CSS Variables](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties),分别为:
+
+-   `var(--semi-color-primary)`:主要
+-   `var(--semi-color-secondary)`:次要
+-   `var(--semi-color-tertiary)`:第三
+-   `var(--semi-color-warning)`:警告
+-   `var(--semi-color-danger)`:危险
+
+你可以直接使用这些主题色定义你的元素。
+
+```jsx live=true dir="column"
+import React from 'react';
+
+function ButtonDemo() {
+  const types = [['primary', '主要'], ['secondary', '次要'], ['tertiary', '第三'], ['warning', '警告'], ['danger', '危险']];
+
+  return (
+    <article>
+      {types.map((type, index) => (
+        <strong key={index} style={{ color: `var(--semi-color-${Array.isArray(type) ? type[0] : type})`, marginRight: 10 }}>{Array.isArray(type) ? type[1]: type}</strong>
+      ))}
+    </article>
+  );
+}
+```
+
+### 按钮主题
+
+目前可用的主题(theme)为:
+
+-   `light`:浅色背景
+-   `solid`:深色背景
+-   `borderless`:无背景
+
+默认的主题为 `light`
+
+#### 浅色背景
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <>
+      <Button theme='light' type='primary' style={{ marginRight: 8 }}>浅色主要</Button>
+      <Button theme='light' type='secondary' style={{ marginRight: 8 }}>浅色次要</Button>
+      <Button theme='light' type='tertiary' style={{ marginRight: 8 }}>浅色第三</Button>
+      <Button theme='light' type='warning' style={{ marginRight: 8 }}>浅色警告</Button>
+      <Button theme='light' type='danger' style={{ marginRight: 8 }}>浅色危险</Button>
+    </>
+  );
+}
+
+```
+
+#### 深色背景
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <>
+      <Button theme='solid' type='primary' style={{ marginRight: 8 }}>深色主要</Button>
+      <Button theme='solid' type='secondary' style={{ marginRight: 8 }}>深色次要</Button>
+      <Button theme='solid' type='tertiary' style={{ marginRight: 8 }}>深色第三</Button>
+      <Button theme='solid' type='warning' style={{ marginRight: 8 }}>深色警告</Button>
+      <Button theme='solid' type='danger' style={{ marginRight: 8 }}>深色危险</Button>
+    </>
+  );
+}
+
+```
+
+#### 无背景
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <>
+      <Button theme='borderless' type='primary' style={{ marginRight: 8 }}>主要</Button>
+      <Button theme='borderless' type='secondary' style={{ marginRight: 8 }}>次要</Button>
+      <Button theme='borderless' type='tertiary' style={{ marginRight: 8 }}>第三</Button>
+      <Button theme='borderless' type='warning' style={{ marginRight: 8 }}>警告</Button>
+      <Button theme='borderless' type='danger' style={{ marginRight: 8 }}>危险</Button>
+    </>
+  );
+}
+
+```
+
+### 尺寸
+
+默认定义了三种尺寸:
+
+-   大:"large"
+-   默认:"default"
+-   小:"small"
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button size='large' style={{marginRight:8}}>大尺寸</Button>
+      <Button size='default' style={{marginRight:8}}>默认尺寸</Button>
+      <Button size='small'>小尺寸</Button>
+    </div>
+  );
+}
+```
+
+### 块级按钮
+
+块级按钮具有预先定义好的宽度,它的宽度与按钮里面内容的宽度无关。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button block>块级按钮</Button>
+    </div>
+  );
+}
+```
+
+### 图标按钮
+
+可定义按钮的图标。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+import { IconCamera, IconSidebar, IconChevronDown } from '@douyinfe/semi-icons';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <strong>默认状态:</strong>
+      <Button icon={<IconCamera />}/>
+          <br/><br/>
+      <strong>禁用状态:</strong>
+      <Button disabled icon={<IconCamera />}/>
+          <br/><br/>
+      <strong>复合类型:</strong>
+      <span className="btn-margin-right">
+      <Button type="primary" icon={<IconCamera />}/>
+      <Button type="secondary" icon={<IconCamera />}/>
+      <Button type="warning" icon={<IconCamera />}/>
+      <Button type="danger" icon={<IconCamera />}/>
+      </span>
+          <br/><br/>
+      <strong>更改主题:</strong>
+      <Button icon={<IconCamera />} theme="solid" style={{ marginRight: 10 }}/>
+      <Button icon={<IconCamera />} theme="light"/>
+          <br/><br/>
+      <strong>更改图标位置:</strong>
+      <Button icon={<IconSidebar />} theme="solid" style={{ marginRight: 10 }}>收起</Button>
+      <Button icon={<IconChevronDown />} theme="solid" iconPosition={"right"}>展开选项</Button>
+          <br/><br/>
+    </div>
+  );
+}
+```
+
+### 链接按钮
+
+我们推荐使用 Typography 的 link 属性来实现链接型的文字按钮,具体用法详见[Typography](/zh-CN/basic/typography)
+
+```jsx live=true
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+import { IconLink } from '@douyinfe/semi-icons';
+
+function Demo() {
+  const { Text } = Typography;
+  return (
+    <div>
+      <Text link={{ href: 'https://semi.design/' }}>链接文本</Text>
+      <br />
+      <br />
+      <Text link={{ href: 'https://semi.design/' }}>打开网站</Text>
+      <br />
+      <br />
+      <Text link icon={<IconLink />} underline>带下划线的网页链接</Text>
+    </div>
+  )
+}
+```
+
+### 禁用状态
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+    <div>
+      <Button disabled>禁用</Button>
+      <Button disabled theme="borderless">无背景禁用</Button>
+      <Button disabled theme="light">浅色禁用</Button>
+      <Button disabled theme="borderless" type="primary">无背景主要禁用</Button>
+      <Button disabled theme="solid" type="warning">深色警告禁用</Button>
+    </div>
+  );
+}
+```
+
+### 加载状态
+
+按钮支持加载状态,通过设置 loading 参数值为 true 即可,注意:disabled 状态优先级高于 loading 状态。
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const [saveLoading, setSaveLoading] = useState(false);
+  const [delLoading, setDelLoading] = useState(true);
+  const [repLoading, setRepLoading] = useState(true);
+
+  const reset = status => {
+    status = !!status;
+    setSaveLoading(status);
+    setDelLoading(status);
+    setRepLoading(status);
+  };
+
+  return (
+    <div>
+      <div> 
+        <div className="btn-margin-right" style={{ display: 'inline-flex', alignItems: 'center', paddingBottom: 14 }}>
+          <Button onClick={() => reset(false)}>关闭加载态</Button>
+          <Button onClick={() => reset(true)}>开启加载态</Button>
+        </div>
+      </div>
+      <hr/>
+      <Button loading={saveLoading} onClick={() => setSaveLoading(true)} style={{ marginRight: 14 }}>保存</Button>
+      <Button loading={delLoading} icon={<IconDelete />} type="danger" onClick={() => setDelLoading(true)} style={{ marginRight: 14 }}>删除</Button>
+      <div style={{ width: 200, display: 'inline-block'}}>
+        <Button loading={repLoading} type="warning" block theme="solid" onClick={() => setRepLoading(true)}>撤销</Button>
+      </div>
+    </div>
+  );
+}
+```
+
+### 按钮组合
+
+可以将多个按钮放入`ButtonGroup`的容器中,通过设置`size`,`disabled`,`type`可统一设置按钮组合中的按钮尺寸,是否禁用和类型。
+
+#### 组合尺寸
+
+```jsx live=true dir="column"
+import React from 'react';
+import { ButtonGroup, Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const sizes = ['large', 'default', 'small'];
+
+  return (
+  <div style={{ display: 'flex' }}>
+    {sizes.map(size => (
+      <div style={{ marginRight: 10 }} key={size}>
+        <ButtonGroup size={size}>
+          <Button>拷贝</Button>
+          <Button>查询</Button>
+          <Button>剪切</Button>
+        </ButtonGroup>
+      </div>
+    ))}
+  </div>
+  );
+}
+```
+
+#### 组合禁用
+
+```jsx live=true dir="column"
+import React from 'react';
+import { ButtonGroup, Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  return (
+  <div style={{ display: 'flex' }}>
+    <div style={{ marginRight: 10 }}>
+      <ButtonGroup disabled>
+        <Button>拷贝</Button>
+        <Button>查询</Button>
+        <Button>剪切</Button>
+      </ButtonGroup>
+    </div>
+  </div>
+  );
+}
+```
+
+#### 组合类型
+
+```jsx live=true dir="column"
+import React from 'react';
+import { ButtonGroup, Button } from '@douyinfe/semi-ui';
+
+function ButtonDemo() {
+  const types = ['primary', 'secondary', 'tertiary', 'warning', 'danger'];
+
+  return (
+  <div style={{ display: 'flex' }}>
+    {types.map(type => (
+      <div style={{ marginRight: 10 }} key={type}>
+        <ButtonGroup type={type}>
+          <Button>拷贝</Button>
+          <Button>查询</Button>
+          <Button>剪切</Button>
+        </ButtonGroup>
+      </div>
+    ))}
+  </div>
+  );
+}
+```
+
+### 分裂按钮组合
+
+**V1.12.0新增**
+
+在`Button`和`Dropdown`结合的场景下,可以使用分裂按钮,分裂按钮添加了按钮之间的间隔,并改变了按钮的边框圆角
+
+#### 基础使用
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { SplitButtonGroup, Dropdown, Button } from '@douyinfe/semi-ui';
+import { IconTreeTriangleDown } from '@douyinfe/semi-icons';
+
+function SplitButtonDemo(){
+
+  const menu = [
+    { node: 'item', name: '编辑项目', onClick: () => console.log('编辑项目点击') },
+    { node: 'item', name: '重置项目' },
+    { node: 'divider' },
+    { node: 'item', name: '复制项目' },
+    { node: 'item', name: '从项目创建模版' },
+    { node: 'divider' },
+    { node: 'item', name: '删除项目', type: 'danger' },
+  ];
+
+  const [btnVisible,setBtnVisible] = useState({
+    1:false,
+    2:false,
+    3:false
+  })
+
+  const handleVisibleChange = (key,visible)=>{
+    newBtnVisible = {...btnVisible};
+    newBtnVisible[key] = visible;
+    setBtnVisible(newBtnVisible)
+  }
+
+  return (
+    <div>
+      <SplitButtonGroup style={{marginRight:10}}>
+        <Button theme="solid" type="primary">分裂按钮</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(1,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[1]?{background:'var(--semi-color-primary-hover)',padding:'8px 4px'}:{padding:'8px 4px'}} theme="solid" type="primary" icon={<IconTreeTriangleDown />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+      <SplitButtonGroup style={{marginRight:10}}>
+        <Button theme="light" type="primary">分裂按钮</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(2,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[2]?{background:'var(--semi-color-fill-1)',padding:'8px 4px'}:{padding:'8px 4px'}}  theme="light" type="primary" icon={<IconTreeTriangleDown />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+      <SplitButtonGroup>
+        <Button style={btnVisible[3]?{background:'var(--semi-color-fill-0)'}:{}} theme="borderless" type="primary">分裂按钮</Button>
+        <Dropdown onVisibleChange={(v)=>handleVisibleChange(3,v)} menu={menu} trigger="click" position="bottomRight">
+          <Button style={btnVisible[3]?{background:'var(--semi-color-fill-1)',padding:'8px 4px'}:{padding:'8px 4px'}}  theme="borderless" type="primary" icon={<IconTreeTriangleDown />}></Button>
+        </Dropdown>
+      </SplitButtonGroup>
+    </div>
+  )
+}
+```
+
+## API 参考
+
+### Button
+
+| 属性                | 说明                                                                                                       | 类型                            | 默认值    |
+| ------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------- | --------- |
+| block               | 将按钮设置为块级按钮                                                                                       | bool                            | false     |
+| className           | 类名                                                                                                       | string                          |           |
+| disabled            | 禁用状态                                                                                                   | boolean                         | false     |
+| htmlType           | 设置 `button` 原生的 `type` 值,可选值:`button`、`reset`、`submit`                                        | string                          | "button"  |
+| icon                | 图标                                                                                                       | ReactNode               |           |
+| iconPosition        | 图标位置,可选值:`left`\|`right`                                                                          | string                          | `left`    |
+| loading             | 加载状态                                                                                                   | boolean                         | false     |
+| noHorizontalPadding | 设置水平方向是否去掉内边距,只对设置了 icon 的 Button 有效。可选值:`true`(等效于 \["left", "right"\]),"left","right",\["left", "right"\] | boolean\|string\|Array<string\> | false     |
+| size                | 按钮大小,可选值:`large`、`default`、`small`                                                              | string                          | "default" |
+| style               | 自定义样式                                                                                                 | CSSProperties                          |           |
+| theme               | 按钮主题,可选值:`solid`(有背景色)、 `borderless`(无背景色)、 `light`(浅背景色)                     | string                          | "light"   |
+| type                | 类型,可选值:`primary`、`secondary`、`tertiary`、`warning`、 `danger`                                     | string                          | "primary" |
+| onClick             | 单击事件                                                                                                   | function(MouseEvent)                        |           |
+| onMouseDown             | 鼠标按下事件                                                                                                   | function(MouseEvent)                        |           |
+| onMouseEnter             | 鼠标移入事件                                                                                                   | function(MouseEvent)                        |           |
+| onMouseLeave             | 鼠标移出事件                                                                                                   | function(MouseEvent)                        |           |
+
+### ButtonGroup
+
+| 属性     | 说明                                                                   | 类型    | 默认值    |
+| -------- | ---------------------------------------------------------------------- | ------- | --------- |
+| disabled | 禁用状态                                                               | boolean | false     |
+| size     | 按钮大小,可选值:`large`、`default`、`small`                          | string  | "default" |
+| theme               | 按钮主题,可选值:`solid`(有背景色)、 `borderless`(无背景色)、 `light`(浅背景色)                     | string                          | "light"   |
+| type     | 类型,可选值:`primary`、`secondary`、`tertiary`、`warning`、 `danger` | string  | "primary" |
+
+### SplitButtonGroup **V1.12.0新增**
+| 属性          | 说明                                                            | 类型      | 默认值     |
+| -----------  | --------------------------------------------------------------  | -------- | --------- |
+| style     | 自定义样式                               | CSSProperties   |         |
+| className     | 自定义类名                               | string   |         |
+
+## 设计变量
+<DesignToken/>
+
+## FAQ
+- #### 为什么Button中的icon属性不起作用?  
+  请检查你的Button import路径,正确的import路径应该为```import { Button } from '@douyinfe/semi-ui;'```,如果你错误地从 @douyinfe/semi-ui/button/button中import的话,获取到的是不带icon功能的基础Button组件
+
+<!-- ## 相关物料
+```material
+5
+``` -->

+ 1469 - 0
content/input/cascader/index-en-US.md

@@ -0,0 +1,1469 @@
+---
+localeCode: en-US
+order: 17
+category: Input
+title:  Cascader
+subTitle: Cascade
+icon: doc-cascader
+brief: Used to select an option under a multi-level classification.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { Cascader } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+Basic usage, only leaf nodes can be selected by default.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <Cascader
+        style={{ width: 400 }}
+        treeData={treeData}
+        placeholder="Please select"
+    />
+  )
+}
+```
+
+### Multiple
+version: >= 1.28.0
+
+Set `multiple` to make multiple selections.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <Cascader
+        defaultValue= {['impressionism','visualArts','Monet']}
+        style={{ width: 400 }}
+        treeData={treeData}
+        placeholder="Please select"
+        multiple
+    />
+  )
+}
+```
+
+### Searchable
+
+Use `filterTreeNode` to support search input. By default it searches the `value` property of the data. You can use `treeNodeFilterProp` to set another property to search or pass in a function to `filterTreeNode` to customize search behavior.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <div>
+        <Cascader
+            style={{ width: 400 }}
+            treeData={treeData}
+            placeholder="Search in label by default"
+            filterTreeNode
+        />
+        <br/>
+        <br/>
+        <Cascader
+            style={{ width: 400 }}
+            treeData={treeData}
+            placeholder="Search in value"
+            filterTreeNode
+            treeNodeFilterProp='value'
+        />
+    </div>
+  )
+}
+```
+
+
+### Searchable Multiple Selection 
+
+version: >= 1.28.0
+
+When multiple selection and search are supported at the same time, in this scenario, you can delete the corresponding selected item by pressing the BackSpace key.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value: ['impressionism','visualArts','Monet']
+        };
+    }
+    onChange(value) {
+        this.setState({value});
+    }
+    render() {
+        const treeData = [
+            {
+                label: 'Impressionism',
+                value: 'impressionism',
+                children: [
+                    {
+                        label: 'Visual Arts',
+                        value: 'visualArts',
+                        children: [
+                            {
+                                label: 'Claude Monet',
+                                value: 'Monet',
+                            },
+                            {
+                                label: 'Pierre-Auguste Renoir',
+                                value: 'Renoir',
+                            },
+                            {
+                                label: 'Édouard Manet',
+                                value: 'Manet',
+                            },
+                        ],
+                    },
+                    {
+                        label: 'Music',
+                        value: 'music',
+                        children: [
+                            {
+                                label: 'Claude Debussy',
+                                value: 'Debussy',
+                            },
+                            {
+                                label: 'Maurice Ravel',
+                                value: 'Ravel',
+                            }
+                        ]
+                    }
+                ],
+            }];
+        return (
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="Please select"
+                value={this.state.value}
+                multiple
+                filterTreeNode
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+### Limit Tags Displayed
+
+version: >= 1.28.0
+
+When multiple selections, you can use `maxTagCount` to limit the number of tags displayed, and the excess will be displayed as +N. 
+
+You can use `showRestTagsPopover` to set whether hover +N displays Popover after maxTagCount is exceeded, the default is false. And, you can also configure Popover in the `restTagsPopoverProps` property.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Impressionism',
+            value: 'impressionism',
+            children: [
+                {
+                    label: 'Visual Arts',
+                    value: 'visualArts',
+                    children: [
+                        {
+                            label: 'Claude Monet',
+                            value: 'Monet',
+                        },
+                        {
+                            label: 'Pierre-Auguste Renoir',
+                            value: 'Renoir',
+                        },
+                        {
+                            label: 'Édouard Manet',
+                            value: 'Manet',
+                        },
+                    ],
+                },
+                {
+                    label: 'Music',
+                    value: 'music',
+                    children: [
+                        {
+                            label: 'Claude Debussy',
+                            value: 'Debussy',
+                        },
+                        {
+                            label: 'Maurice Ravel',
+                            value: 'Ravel',
+                        }
+                    ]
+                }
+            ],
+        }];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="Please selection"
+            multiple
+            maxTagCount={1}
+            showRestTagsPopover={true}
+            restTagsPopoverProps={{ position: 'top' }}
+            defaultValue={[
+                ['impressionism', 'visualArts', 'Monet'],
+                ['impressionism', 'visualArts', 'Renoir']
+            ]}
+        />
+    )
+}
+```
+
+
+### Limit Tags Number
+
+version: >= 1.28.0
+
+In a multi-selection scene, use max to limit the number of multi-selection selections. After max is exceeded, the onExceed callback will be triggered.
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Toast } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Impressionism',
+            value: 'impressionism',
+            children: [
+                {
+                    label: 'Visual Arts',
+                    value: 'visualArts',
+                    children: [
+                        {
+                            label: 'Claude Monet',
+                            value: 'Monet',
+                        },
+                        {
+                            label: 'Pierre-Auguste Renoir',
+                            value: 'Renoir',
+                        },
+                        {
+                            label: 'Édouard Manet',
+                            value: 'Manet',
+                        },
+                    ],
+                },
+                {
+                    label: 'Music',
+                    value: 'music',
+                    children: [
+                        {
+                            label: 'Claude Debussy',
+                            value: 'Debussy',
+                        },
+                        {
+                            label: 'Maurice Ravel',
+                            value: 'Ravel',
+                        }
+                    ]
+                }
+            ],
+        }];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="Please selection"
+            multiple
+            max={1}
+            onExceed={v=>{
+                Toast.warning('exceed max');
+                console.log(v);
+            }}
+            defaultValue={[
+                ['impressionism', 'visualArts', 'Monet']
+            ]}
+        />
+    )
+}
+```
+
+### Change on Select
+
+In the case of single selection, you can also set `changeOnSelect` to allow the parent option to be selected.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <div>
+    <Cascader
+        style={{ width: 400 }}
+        treeData={treeData}
+        changeOnSelect
+        placeholder="Change on select"
+    />
+    <br/>
+    <br/>
+    <Cascader
+        style={{ width: 400 }}
+        treeData={treeData}
+        changeOnSelect
+        placeholder="Searchable change on select"
+        filterTreeNode
+    />
+    </div>
+  )
+}
+```
+
+### Custom Display Property
+
+Set `displayProp` to select which property in the data you would like to display. By default, `label` is displayed.
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Impressionism',
+            value: 'impressionism',
+            children: [
+                {
+                    label: 'Visual Arts',
+                    value: 'visualArts',
+                    children: [
+                        {
+                            label: 'Claude Monet',
+                            value: 'Monet',
+                        },
+                        {
+                            label: 'Pierre-Auguste Renoir',
+                            value: 'Renoir',
+                        },
+                        {
+                            label: 'Édouard Manet',
+                            value: 'Manet',
+                        },
+                    ],
+                },
+                {
+                    label: 'Music',
+                    value: 'music',
+                    children: [
+                        {
+                            label: 'Claude Debussy',
+                            value: 'Debussy',
+                        },
+                        {
+                            label: 'Maurice Ravel',
+                            value: 'Ravel',
+                        }
+                    ]
+                }
+            ],
+        }
+    ];
+  return (
+        <>
+            <Typography.Title heading={6}>single selection</Typography.Title>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="Please Select"
+                displayProp='value'
+                defaultValue={['impressionism', 'visualArts', 'Monet']}
+            />
+            <br />
+            <br />
+            <Typography.Title heading={6}>multiple selection</Typography.Title>
+            <Cascader
+                multiple
+                style={{ width: 300 }}
+                treeData={treeData}                
+                defaultValue={['impressionism', 'visualArts', 'Monet']}
+                placeholder="Please Select"
+                displayProp='value'
+            />
+        </>
+    );
+}
+```
+
+The return format can be set by setting `displayRender`.
+
+When single selection (`multiple=false`), `displayRender((labelPath: string[]) => ReactNode)`, where labelPath is a path array composed of labels.
+
+When multiple selection (`multiple=true`), `displayRender((item: Entity, index: number) => ReactNode)`, where item is the relevant data of the node.
+
+```typescript
+interface Entity {
+    children?: Entity[];         // children list
+    data: treeNode;              // treedata
+    ind: number;                 // index
+    key: string;                 // key
+    level: number;               // node level
+    parent?: Entity;             // parent data
+    parentKey?: string;          // parent key
+    path: string[];              // key path
+    valuePath: string[];         // value path
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Tag, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Impressionism',
+            value: 'impressionism',
+            children: [
+                {
+                    label: 'Visual Arts',
+                    value: 'visualArts',
+                    children: [
+                        {
+                            label: 'Claude Monet',
+                            value: 'Monet',
+                        },
+                        {
+                            label: 'Pierre-Auguste Renoir',
+                            value: 'Renoir',
+                        },
+                        {
+                            label: 'Édouard Manet',
+                            value: 'Manet',
+                        },
+                    ],
+                },
+                {
+                    label: 'Music',
+                    value: 'music',
+                    children: [
+                        {
+                            label: 'Claude Debussy',
+                            value: 'Debussy',
+                        },
+                        {
+                            label: 'Maurice Ravel',
+                            value: 'Ravel',
+                        }
+                    ]
+                }
+            ],
+        }
+    ];
+    return (
+        <>
+            <Typography.Title heading={6}>single selection</Typography.Title>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="Please select"
+                displayRender={list => 'Selected:' + list.join(' -> ')}
+                defaultValue={['impressionism', 'visualArts', 'Monet']}
+            />
+            <br />
+            <br />
+            <Typography.Title heading={6}>multiple selection</Typography.Title>
+            <Cascader
+                multiple
+                style={{ width: 300 }}
+                treeData={treeData}
+                defaultValue={['impressionism', 'visualArts', 'Monet']}
+                placeholder="Please select"
+                displayRender={(item, idx) => (
+                    <Tag
+                        style={{marginRight: 4}}
+                        color='white'
+                        key={`${idx}-${item.data.label}`}
+                    >
+                        {item.data.label}
+                    </Tag>
+                )}
+            />
+        </>
+    )
+}
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <div>
+      <Cascader
+          style={{ width: 400 }}
+          treeData={treeData}
+          placeholder="Please select"
+          disabled
+      />
+      <br />
+      <br />
+      <Cascader
+          style={{ width: 400 }}
+          treeData={treeData}
+          placeholder="Please select"
+          defaultValue={['impressionism', 'music', 'Debussy']}
+          filterTreeNode
+          disabled
+      />
+    </div>
+  )
+}
+```
+
+### Disable Strictly
+
+version: >= 1.32.0
+
+You can use disableStrictly to enable strict disabling. After enabling strict disabling, when the node is disabled, the selected state cannot be changed through the relationship between the child or the parent.
+
+Take the following demo as an example, the node "Music" is strictly disabled. Therefore, when we change the selected state of its parent node "Impressionism", it will not affect the selected state of the node "Music".
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                disabled: true,
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            multiple
+            placeholder="Please select..."
+            disableStrictly
+        />
+  )
+}
+```
+
+### the Way of Expand Menu
+
+version: >= 1.29.0
+
+You can use `showNext` to set the time to expand the Dropdown submenu, optional: `click` (default), `hover`.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+        <Cascader
+            style={{ width: 400 }}
+            treeData={treeData}
+            placeholder="Please select"
+            showNext="hover"
+        />
+  )
+}
+```
+
+### Additional items
+
+We have reserved slots at the top and bottom of the cascade selector. You can set them through bottomSlot or topSlot.
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Typography } from '@douyinfe/semi-ui';
+
+() => {
+  const { Text } = Typography;
+  const slotStyle = {
+        height: '36px',
+        display: 'flex',
+        padding: '0 32px',
+        alignItems: 'center',
+        cursor: 'pointer',
+        borderTop: '1px solid var(--semi-color-border)'
+  };
+  const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+  return (
+    <Cascader
+        style={{ width: 300 }}
+        treeData={treeData}
+        placeholder="Please select"
+        bottomSlot={
+            <div style={slotStyle}>
+                <Text>Can't find a relevant option?</Text>
+                <Text link>Go to create</Text>
+            </div>
+        }
+    />
+  )
+}
+
+```
+
+### Controlled Component
+
+You can use `value` along with `onChange` property if you want to use Cascader as a controlled component.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: []
+        };
+    }
+    onChange(value) {
+        this.setState({value})
+    }
+    render() {
+            const treeData = [
+    {
+        label: 'Impressionism',
+        value: 'impressionism',
+        children: [
+            {
+                label: 'Visual Arts',
+                value: 'visualArts',
+                children: [
+                    {
+                        label: 'Claude Monet',
+                        value: 'Monet',
+                    },
+                    {
+                        label: 'Pierre-Auguste Renoir',
+                        value: 'Renoir',
+                    },
+                    {
+                        label: 'Édouard Manet',
+                        value: 'Manet',
+                    },
+                ],
+            },
+            {
+                label: 'Music',
+                value: 'music',
+                children: [
+                    {
+                        label: 'Claude Debussy',
+                        value: 'Debussy',
+                    },
+                    {
+                        label: 'Maurice Ravel',
+                        value: 'Ravel',
+                    }
+                ]
+            }
+        ],
+    }];
+        return (
+            <Cascader
+                style={{ width: 400 }}
+                treeData={treeData}
+                placeholder="Please select"
+                value={this.state.value}
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+
+### Auto Merge Value
+
+In the multi-selection (multiple=true) scenario, when we select the ancestor node, if we want the value not to include its corresponding descendant nodes, we can set it by `autoMergeValue`, and the default is true.
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: ['impressionism','visualArts']
+        };
+    }
+    onChange(value) {
+        this.setState({value})
+    }
+    render() {
+        const treeData = [
+            {
+                label: 'Impressionism',
+                value: 'impressionism',
+                children: [
+                    {
+                        label: 'Visual Arts',
+                        value: 'visualArts',
+                        children: [
+                            {
+                                label: 'Claude Monet',
+                                value: 'Monet',
+                            },
+                            {
+                                label: 'Pierre-Auguste Renoir',
+                                value: 'Renoir',
+                            },
+                            {
+                                label: 'Édouard Manet',
+                                value: 'Manet',
+                            },
+                        ],
+                    },
+                    {
+                        label: 'Music',
+                        value: 'music',
+                        children: [
+                            {
+                                label: 'Claude Debussy',
+                                value: 'Debussy',
+                            },
+                            {
+                                label: 'Maurice Ravel',
+                                value: 'Ravel',
+                            }
+                        ]
+                    }
+                ],
+            }
+        ];
+        return (
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="Please select"
+                value={this.state.value}
+                multiple
+                autoMergeValue={false}
+                onChange={e => this.onChange(e)}
+            />
+        );
+    }
+}
+```
+
+### Dynamic Update of Data
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Button } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            treeData: [],
+        }
+        this.add = this.add.bind(this);
+    }
+    add() {
+        let itemLength = Math.floor(Math.random() * 3) + 1;
+        let treeData = new Array(itemLength).fill(0).map((v, i) => {
+            let length = Math.floor(Math.random() * 3);
+            let children = new Array(length).fill(0).map((cv, ci) => {
+                let child = {
+                    key: `${i}-${ci}`,
+                    label: `Item-${i}-${ci}`,
+                    value: `${i}-${ci}`
+                }
+                return child;
+            });
+            let item = {
+                key: `${i}`,
+                label: `Item-${i}`,
+                value: `${i}`,
+                children
+            };
+            return item;
+        })
+        this.setState({ treeData });
+    }
+    render() {
+        return (
+            <>
+                <Cascader
+                    style={{ width: 400 }}
+                    treeData={this.state.treeData}
+                    placeholder="Please select"
+                />
+                <br/>
+                <br/>
+                <Button onClick={this.add}>
+                    Update Data
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### Deep & long list
+
+When your data structure level is particularly deep, the Cascader drop-down menu may be at the top of the screen. At this time, we recommend setting overflow -x: auto and a suitable width for the drop-down menu (it is recommended to use a width of N+0.5 columns, the most Expand to display half a column to give users a visual cue that they can scroll in the horizontal direction)
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'A',
+        value: 'A',
+        children: [
+            {
+                label: 'B',
+                value: 'B',
+                children: [
+                    {
+                        label: 'C',
+                        value: 'C',
+                        children: [
+                            {
+                                label: 'D',
+                                value: 'D',
+                                children: [
+                                    {
+                                        label: 'E',
+                                        value: 'E',
+                                        children: [
+                                            {
+                                                label: 'F',
+                                                value: 'F',
+                                            }
+                                        ]
+                                    }
+                                ]
+                            }
+                        ]
+                    }
+                ],
+            }
+        ]
+    }
+  ];
+  return (
+    <Cascader
+        dropdownClassName='components-cascader-demo'
+        style={{ width: 300 }}
+        treeData={treeData}
+    />
+  )
+}
+```
+
+```css
+.components-cascader-demo {
+    .semi-cascader-option-lists {
+        max-width: 510px;
+        overflow-x: auto;
+    }
+}
+```
+
+### Load Async Data
+You could use `loadData` to load data asynchronously.
+**v>=1.8.0**  
+**Could not be used together with searching**
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const initialData = [
+        {
+            label: 'Node1',
+            value: '0-0',
+        },
+        {
+            label: 'Node2',
+            value: '0-1',
+        },
+        {
+            label: 'Node3',
+            value: '0-2',
+            isLeaf: true
+        },
+    ];
+    const [data, setData] = useState(initialData);
+    
+    const updateTreeData = (list, value, children) => {
+        return list.map(node => {
+            if (node.value === value) {
+                return { ...node, children };
+            }
+            if (node.children) {
+                return { ...node, children: updateTreeData(node.children, value, children) };
+            }
+            return node;
+        });
+    }
+
+    const onLoadData = selectedOpt => {
+        const targetOpt = selectedOpt[selectedOpt.length - 1];
+        const { label, value } = targetOpt;
+        return new Promise(resolve => {
+            if (targetOpt.children) {
+                resolve();
+                return;
+            }
+
+            setTimeout(() => {
+                setData(origin =>
+                    updateTreeData(origin, value, [
+                        {
+                          label: `${label} - 1`,
+                          value: `${label}-1`,
+                          isLeaf: selectedOpt.length > 1
+                        },
+                        {
+                          label: `${label} - 2`,
+                          value: `${label}-2`,
+                          isLeaf: selectedOpt.length > 1
+                        },
+                      ]),
+                );
+                resolve();
+            }, 1000)
+        })
+    }
+
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={data}
+            loadData={onLoadData}
+            placeholder="Please select"
+        />
+    );
+}
+```
+
+
+### Custom Trigger
+
+If the default trigger style cannot meet your needs, you can use `triggerRender` to customize the display of the select box
+
+The parameters of triggerRender are as follows
+
+
+```typescript
+interface TriggerRenderProps {
+    /* All props passed to Cascader by users */
+    componentProps: CascaderProps;
+    /* Whether to disable Cascader */
+    disabled: boolean;
+    /**
+     * The hierarchical position of the selected node in treeData,
+     *  as in the following example, when "Asia-China-Beijing" is 
+     *  selected, the value here is 0-0-1
+     */
+    value?: string;
+    /* The input value of the current Input box */
+    inputValue: string;
+    /**
+     * The function used to update the value of the input box. You
+     *  should call this function when the value of the Input component
+     *  customized by triggerRender is updated to synchronize the
+     *  state with Cascader
+     */
+    onChange: (inputValue: string) => void;
+    /* Function to clear the value */
+    onClear: () => void;
+    /* Placeholder of Cascader */
+    placeholder?: string;
+}
+```
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { Cascader, Button } from '@douyinfe/semi-ui';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+            {
+                label: 'Asia',
+                value: 'asia',
+                children: [
+                    {
+                        label: 'China',
+                        value: 'china',
+                        children: [
+                            {
+                                label: 'Guangdong',
+                                value: 'guangdong',
+                            },
+                            {
+                                label: 'Beijing',
+                                value: 'beijing',
+                            },
+                            {
+                                label: 'Shanghai',
+                                value: 'shanghai',
+                            },
+                        ],
+                    },
+                    {
+                        label: 'Koera',
+                        value: 'koera',
+                        children: [
+                            {
+                                label: 'Seoul',
+                                value: 'seoul',
+                            }
+                        ]
+                    },
+                ],
+            }
+        ], []);
+    const onChange = useCallback((val) => {
+        setValue(val);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setValue([]);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return value && value.length ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [value]);
+
+    const triggerRender = ({ value: innerStateValue, placeholder, ...rest }) => {
+        return (
+            <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                {value && value.length ? value.join('/') : placeholder}
+            </Button>
+        );
+    };
+
+    return (
+        <Cascader
+            onChange={onChange}
+            value={value}
+            treeData={treeData}
+            placeholder='Custom Trigger'
+            triggerRender={triggerRender}
+        />
+    );
+}
+```
+
+
+## API reference
+
+### Cascader
+
+| Properties         | Instructions                                                                                                                 | type                                                                 | Default                         | version |
+| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------- | ------- |
+| arrowIcon     | Customize the right drop-down arrow Icon, when the showClear switch is turned on and there is currently a selected value, hover will give priority to the clear icon                                                                                   | ReactNode                                                              |                            | 1.15.0       |
+| autoAdjustOverflow | Whether to automatically adjust the expansion direction of the dropdown for automatic adjustment of the expansion direction during edge occlusion | boolean | true | - |
+| autoMergeValue | Auto merge value. Specifically, after opening, when a parent node is selected, the value will not include the descendants of the node | boolean | true |  1.28.0 |
+| bottomSlot | bottom slot | ReactNode | - |  1.27.0 |
+| changeOnSelect     | Toggle whether non-leaf nodes are selectable                                                                                   | boolean                                                              | false                           | -       |
+| className          | ClassName                                                                                                                    | string                                                               | -                               | -       |
+| defaultOpen       | Set whether to open the dropDown by default              | boolean   | false                                | -      |
+| defaultValue       | Default selected value      | string\|number\|TreeNode\|(string\|number\|TreeNode)[]                                                   | -                               | -       |
+| disabled           | Makes the element disabled                                                                                                   | boolean                                                              | false                           | -       |
+| displayProp        | Set the attribute value displayed by the backfill option displayed                                                                                             | string                                                               | `label`                         | -       |
+| displayRender      | Set the backfill format value                                                                                 | (selected: string[] \| Entity, idx?: number) => ReactNode                                            | selected => selected.join ('/') | -       |
+| dropdownClassName  | ClassName property for the drop-down menu                                                                                    | string                                                               | -                               | -       |
+| dropdownStyle      | Inline style of drop-down menu                                                                                               | object                                                               | -                               | -       |
+| emptyContent       | Content displayed when the search has no result                                                                              | ReactNode                                                            | `No result`                     | -       |
+| filterLeafOnly       |  Whether the search results only show the path of leaf nodes   | boolean    | true    | 1.26.0    |
+| filterTreeNode     | Set filter, the value of treeNodeFilterProp is used for searching                | ((inputValue: string, treeNodeString: string) => boolean) \| boolean | false                           | -       |
+| getPopupContainer | Specify the parent DOM, the drop-down box will be rendered into the DOM, the customization needs to set position: relative |() => HTMLElement|() => document.body|-|
+| insetLabel         | Prefix alias, used mainly in Form                                                                                            | ReactNode                                                            | -                               | 0.28.0  |
+| loadData | Load data asynchronously and the return value should be a promise | (selectOptions: TreeNode[]) => Promise< void > |-| 1.8.0|
+| max| In the case of multiple selections, the number of multiple selections is limited, and the onExceed callback will be triggered when max is exceeded | number |-|1.28.0|
+| maxTagCount| When multiple selections, the maximum number of labels to be displayed will be displayed in the form of +N after exceeding| number |-|1.28.0|
+| motion | Set the pop-up animation of the dropdown box |boolean\|object|true|-|
+| mouseEnterDelay | After the mouse is moved in, the time to delay the display of the dropdown box, in milliseconds | number | 50 | - |
+| mouseLeaveDelay | After the mouse is moved out, the time to hide the display of the dropdown box, in milliseconds | number | 50 | - |
+| multiple | Set multiple | boolean | false |  1.28.0 |
+| placeholder        | Placeholder                                                                                                                  | string                                                               | -                               | -       |
+| prefix             | Prefix label                                                                                                                 | ReactNode                                                            | -                               | 0.28.0  |
+|restTagsPopoverProps |The configuration properties of the [Popover](/en-US/show/popover#API%20Reference)     |PopoverProps     | {}        |1.28.0|
+| searchPlaceholder  | Placeholder for search input                                                                                                 | string                                                               | -                               | -       |
+| showClear       |  Toggle whether to show clear button   | boolean    | false    | 0.35.0    |
+| showNext| Set the way to expand the Dropdown submenu, one of: `click`、`hover` | string |`click`|1.29.0|
+| showRestTagsPopover| When the number of tags exceeds maxTagCount and hover reaches +N, whether to display the remaining content through Popover| boolean |false|1.28.0|
+| size               | Selectbox size, one of `large`, `small`, `default`                                                                           | string                                                               | `default`                       | -       |
+| stopPropagation | Whether to prevent the click event on the dropdown box from bubbling | boolean | true | - |
+| disableStrictly | Set whether to enable strict prohibition. After opening, when the node is disabled, the selected state cannot be changed through the relationship between the child or the parent | boolean | false | 1.32.0|
+| style              | Inline style                                                                                                                 | CSSProperties                                                               | -                               | -       |
+| suffix             | Suffix label                                                                                                                 | ReactNode                                                            | -                               | 0.28.0  |
+| topSlot | top slot | ReactNode | - |  1.27.0 |
+| treeData           | Render data. Refer to [TreeNode](#TreeNode)  for detailed formatting. | TreeNode[]                                                      | \ []                            | -       |
+| treeNodeFilterProp | When searching, the input item filters the corresponding treeNode property.                                                  | string                                                               | `label`                         | -       |
+| triggerRender | Method to create a custom trigger  | (triggerRenderData: object) => ReactNode | - | 0.34.0 |
+| value       | Selected value (controlled mode)    | string\|number\|TreeNode\|(string\|number\|TreeNode)[][]                                                   | -                               | -       |
+| validateStatus |The validation status of the trigger only affects the display style. Optional: default、error、warning | string | `default` | - |
+| zIndex | zIndex for dropdown menu | number | 1030 | - |
+| onBlur | Out of focus Cascader's callback | (e: MouseEvent) => void | - | - |
+| onChange           | Callback function when the tree node is selected                                                                             | (value: string\|number\|TreeNode\|(string\|number\|TreeNode)[]) => void                                | -                               | -       |
+| onClear| When showClear is true, click the clear button to trigger the callback | () => void |-|1.29.0|
+| onChangeWithObject | Toggle whether to return all properties in an option as a return value. When set to true, return value looks like TreeNode. For controlled mode, you need to pass TreeNode to value correspondingly. DefaultValue similarly. | boolean | false | 1.16.0 |
+| onDropdownVisibleChange       | Callback function when dropdown menu visibility changes   | (visible: boolean) => void        | -                                | 0.35.0    |
+| onExceed| When multiple selections are made, the callback triggered after max is exceeded | (checkedItem: Entity[]) => void |-|1.28.0|
+| onFocus| Focus on Cascader's callback | (e: MouseEvent) => void | - | - |
+| onListScroll | Callback function when panel list scroll | (e: React.Event, panel: { panelIndex: number; activeNode: TreeNode; } ) => void | - | 1.15.0 |
+| onLoad | Callback function when a node is loaded | (newLoadedKeys: Set< string >, data: TreeNode) => void | - | 1.8.0|
+| onSearch           | Callback function when the values for search input changes                                                                   | (value: string) => void                                                             | -                               | -       |
+| onSelect           | Callback function when selected                                                                                              | function(selected: string)                                           | -                               | -       |
+
+### TreeNode
+
+| Properties | Instructions                   | type           | Default |
+| ---------- | -------------------------------| -------------- | ------- |
+| children   | children node                  | TreeNode[]     | -       |
+| disabled   | Disabled status **>=0.35.0**   | boolean        | -       |
+| isLeaf     | leaf node                      | boolean        | -       |
+| label      | Text to be displayed (required)| ReactNode      | -       |
+| loading    | loading                        | boolean        | -       |
+| value      | Value property (required)      | string\|number | -       |
+
+## Design Tokens
+<DesignToken/>

+ 1453 - 0
content/input/cascader/index.md

@@ -0,0 +1,1453 @@
+---
+localeCode: zh-CN
+order: 17
+category: 输入类
+title:  Cascader 级联选择
+icon: doc-cascader
+brief: 用于选择多级分类下的某个选项。
+---
+
+## 代码演示
+
+
+### 如何引入
+
+```jsx import
+import { Cascader } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+最简单的用法,默认只可以选叶子节点。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+        />
+    );
+}
+```
+
+### 多选
+
+version: >= 1.28.0
+
+设置 `multiple`,可以进行多选。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <Cascader
+            defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+            multiple
+        />
+    )
+}
+```
+
+### 可搜索的
+
+通过设置 `filterTreeNode` 属性可支持搜索功能。默认对 `label` 值进行搜索,可通过 `treeNodeFilterProp` 更改。   
+默认搜索结果只会展示叶子结点的路径,想要显示更多的结果,可以设置 `filterLeafOnly` 为 `false`。
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Cascader, Typography } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            },
+            {
+                label: '宁波市',
+                value: 'ningbo',
+                children: [
+                    {
+                        label: '海曙区',
+                        value: 'haishu',
+                    },
+                    {
+                        label: '江北区',
+                        value: 'jiangbei',
+                    }
+                ]
+            },
+        ],
+    }
+  ];
+  return (
+    <div>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="默认对label值进行搜索"
+                filterTreeNode
+            />
+            <br/>
+            <br/>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="对value值进行搜索"
+                filterTreeNode
+                treeNodeFilterProp='value'
+            />
+            <br/>
+            <br/>
+            <Typography.Title heading={6}>filterLeafOnly=false:</Typography.Title>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="默认对label值进行搜索"
+                filterTreeNode
+                filterLeafOnly={false}
+            />
+        </div>
+  )
+}
+```
+
+### 可搜索的多选
+
+version: >= 1.28.0
+
+支持多选和搜索同时使用时,在这种场景下,可以通过按下 BackSpace 键来删除对应的已选项目。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const [value, setValue] = useState(['zhejiang','ningbo','haishu']);
+    const onChange = (val) => { setValue(val) }
+    const treeData = [
+            {
+                label: '浙江省',
+                value: 'zhejiang',
+                children: [
+                    {
+                        label: '杭州市',
+                        value: 'hangzhou',
+                        children: [
+                            {
+                                label: '西湖区',
+                                value: 'xihu',
+                            },
+                            {
+                                label: '萧山区',
+                                value: 'xiaoshan',
+                            },
+                            {
+                                label: '临安区',
+                                value: 'linan',
+                            },
+                        ],
+                    },
+                    {
+                        label: '宁波市',
+                        value: 'ningbo',
+                        children: [
+                            {
+                                label: '海曙区',
+                                value: 'haishu',
+                            },
+                            {
+                                label: '江北区',
+                                value: 'jiangbei',
+                            }
+                        ]
+                    },
+                ],
+            }
+        ];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+            value={value}
+            multiple
+            filterTreeNode
+            onChange={e => onChange(e)}
+        />
+    )
+}
+```
+
+### 限制标签展示数量
+
+version: >= 1.28.0
+
+在多选的场景中,利用 maxTagCount 可以限制展示的标签数量,超出部分将以 +N 的方式展示。
+
+使用 showRestTagsPopover 可以设置在超出 maxTagCount 后,hover +N 是否显示 Popover,默认为 false。并且,还可以在 restTagsPopoverProps 属性中配置 Popover。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+            multiple
+            showRestTagsPopover={true}
+            restTagsPopoverProps={{ position: 'top' }}
+            maxTagCount={1}
+            defaultValue={[
+                ['zhejiang', 'ningbo', 'haishu'],
+                ['zhejiang', 'hangzhou', 'xihu']
+            ]}
+        />
+    )
+}
+```
+
+### 限制选中数量
+
+version: >= 1.28.0
+
+在多选的场景中,利用 max 可以限制多选选中的数量。超出 max 后将触发 onExceed 回调。
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Toast } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+            multiple
+            max={1}
+            onExceed={v=>{
+                Toast.warning('exceed max');
+                console.log(v);
+            }}
+            defaultValue={['zhejiang', 'ningbo', 'haishu']}
+        />
+    )
+}
+```
+
+### 选择即改变
+
+在单选的情况下,还可以通过设置 `changeOnSelect`,允许选中父级选项。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            },
+            {
+                label: '宁波市',
+                value: 'ningbo',
+                children: [
+                    {
+                        label: '海曙区',
+                        value: 'haishu',
+                    },
+                    {
+                        label: '江北区',
+                        value: 'jiangbei',
+                    }
+                ]
+            },
+        ],
+    }
+  ];
+  return (
+    <div>
+    <Cascader
+        style={{ width: 300 }}
+        treeData={treeData}
+        changeOnSelect
+        placeholder="选择即改变"
+    />
+    <br/>
+    <br/>
+    <Cascader
+        style={{ width: 300 }}
+        treeData={treeData}
+        changeOnSelect
+        placeholder="可搜索的选择即改变"
+        filterTreeNode
+    />
+    </div>
+  )
+}
+```
+
+### 自定义显示
+
+可以通过 `displayProp` 设置回填选项显示的属性值,默认为 `label`。
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <>
+            <Typography.Title heading={6}>单选</Typography.Title>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="回填时显示数据的value值"
+                displayProp='value'
+                defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+            />
+            <br />
+            <br />
+            <Typography.Title heading={6}>多选</Typography.Title>
+            <Cascader
+                multiple
+                style={{ width: 300 }}
+                treeData={treeData}
+                defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+                placeholder="回填时显示数据的value值"
+                displayProp='value'
+            />
+        </>
+    );
+}
+```
+
+可以通过设置 `displayRender` 可以设定返回格式。
+
+单选 (`multiple=false`) 时, `displayRender((labelPath: string[]) => ReactNode)`, 其中 labelPath 是由 label 构成的 path 数组。
+
+多选 (`multiple=true`) 时, `displayRender((item: Entity, index: number) => ReactNode)`, 其中 item 为节点的相关数据。
+
+```typescript
+interface Entity {
+    children?: Entity[];         // children list
+    data: treeNode;              // treedata
+    ind: number;                 // index
+    key: string;                 // key
+    level: number;               // node level
+    parent?: Entity;             // parent data
+    parentKey?: string;          // parent key
+    path: string[];              // key path
+    valuePath: string[];         // value path
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Tag, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: '浙江省',
+            value: 'zhejiang',
+            children: [
+                {
+                    label: '杭州市',
+                    value: 'hangzhou',
+                    children: [
+                        {
+                            label: '西湖区',
+                            value: 'xihu',
+                        },
+                        {
+                            label: '萧山区',
+                            value: 'xiaoshan',
+                        },
+                        {
+                            label: '临安区',
+                            value: 'linan',
+                        },
+                    ],
+                },
+                {
+                    label: '宁波市',
+                    value: 'ningbo',
+                    children: [
+                        {
+                            label: '海曙区',
+                            value: 'haishu',
+                        },
+                        {
+                            label: '江北区',
+                            value: 'jiangbei',
+                        }
+                    ]
+                },
+            ],
+        }
+    ];
+    return (
+        <>
+            <Typography.Title heading={6}>单选</Typography.Title>
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="自定义回填时显示数据的格式"
+                displayRender={list => '已选择:' + list.join(' -> ')}
+                defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+            />
+            <br />
+            <br />
+            <Typography.Title heading={6}>多选</Typography.Title>
+            <Cascader
+                multiple
+                style={{ width: 300 }}
+                treeData={treeData}
+                defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+                placeholder="自定义回填时显示数据的格式"
+                displayRender={(item, idx) => (
+                    <Tag
+                        style={{marginRight: 4}}
+                        color='white'
+                        key={`${idx}-${item.data.label}`}
+                    >
+                        {item.data.label}
+                    </Tag>
+                )}
+            />
+        </>
+    )
+}
+```
+
+### 禁用
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            }
+        ],
+    }
+  ];
+  return (
+    <div>
+      <Cascader
+          style={{ width: 300 }}
+          treeData={treeData}
+          placeholder="请选择所在地区"
+          disabled
+      />
+      <br />
+      <br />
+      <Cascader
+          style={{ width: 300 }}
+          treeData={treeData}
+          placeholder="请选择所在地区"
+          defaultValue={['zhejiang', 'hangzhou', 'xihu']}
+          filterTreeNode
+          disabled
+      />
+    </div>
+  )
+}
+```
+
+### 严格禁用
+
+version: >= 1.32.0
+
+可以使用 disableStrictly 来开启严格禁用。开启严格禁用后,当节点是 disabled 的时候,则不能通过子级或者父级的关系改变选中状态。
+
+以下面的 demo 为例,节点"宁波"开启了严格禁用,因此,当我们改变其父节点"浙江省"的选中状态时,也不会影响到节点"宁波"的选中状态。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            },
+            {
+                label: '宁波市',
+                value: 'ningbo',
+                disabled: true,
+                children: [
+                    {
+                        label: '海曙区',
+                        value: 'haishu',
+                    },
+                    {
+                        label: '江北区',
+                        value: 'jiangbei',
+                    }
+                ]
+            },
+        ],
+    }
+  ];
+  return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            multiple
+            placeholder="请选择所在地区"
+            disableStrictly
+        />
+  )
+}
+```
+
+### 展示子菜单的时机
+
+version: >= 1.29.0
+
+可以使用 `showNext` 设置展开 Dropdown 子菜单的触发时机,可选: `click`(默认)、`hover`。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            }
+        ],
+    }
+  ];
+  return (
+        <Cascader
+            style={{ width: 300 }}
+            treeData={treeData}
+            placeholder="请选择所在地区"
+            showNext="hover"
+        />
+  )
+}
+```
+
+### 在顶部/底部渲染附加项
+
+我们在级联选择器的顶部、底部分别预留了插槽,你可以通过 `topSlot` 或 `bottomSlot` 来设置。
+
+```jsx live=true
+import React from 'react';
+import { Cascader, Typography } from '@douyinfe/semi-ui';
+
+() => {
+  const { Text } = Typography;
+  const slotStyle = {
+        height: '36px',
+        display: 'flex',
+        padding: '0 32px',
+        alignItems: 'center',
+        cursor: 'pointer',
+        borderTop: '1px solid var(--semi-color-border)'
+  };
+  const treeData = [
+    {
+        label: '浙江省',
+        value: 'zhejiang',
+        children: [
+            {
+                label: '杭州市',
+                value: 'hangzhou',
+                children: [
+                    {
+                        label: '西湖区',
+                        value: 'xihu',
+                    },
+                    {
+                        label: '萧山区',
+                        value: 'xiaoshan',
+                    },
+                    {
+                        label: '临安区',
+                        value: 'linan',
+                    },
+                ],
+            },
+            {
+                label: '宁波市',
+                value: 'ningbo',
+                children: [
+                    {
+                        label: '海曙区',
+                        value: 'haishu',
+                    },
+                    {
+                        label: '江北区',
+                        value: 'jiangbei',
+                    }
+                ]
+            },
+        ],
+    }
+  ];
+  return (
+    <Cascader
+        style={{ width: 300 }}
+        treeData={treeData}
+        placeholder="请选择所在地区"
+        bottomSlot={
+            <div style={slotStyle}>
+                <Text>找不大相关选项?</Text>
+                <Text link>去新建</Text>
+            </div>
+        }
+    />
+  )
+}
+```
+
+### 受控
+
+传入 `value` 时即为受控组件,可以配合 `onChange` 使用。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: []
+        };
+    }
+    onChange(value) {
+        this.setState({value})
+    }
+    render() {
+        const treeData = [
+            {
+                label: '浙江省',
+                value: 'zhejiang',
+                children: [
+                    {
+                        label: '杭州市',
+                        value: 'hangzhou',
+                        children: [
+                            {
+                                label: '西湖区',
+                                value: 'xihu',
+                            },
+                            {
+                                label: '萧山区',
+                                value: 'xiaoshan',
+                            },
+                            {
+                                label: '临安区',
+                                value: 'linan',
+                            },
+                        ],
+                    },
+                    {
+                        label: '宁波市',
+                        value: 'ningbo',
+                        children: [
+                            {
+                                label: '海曙区',
+                                value: 'haishu',
+                            },
+                            {
+                                label: '江北区',
+                                value: 'jiangbei',
+                            }
+                        ]
+                    },
+                ],
+            }
+        ];
+        return (
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="请选择所在地区"
+                value={this.state.value}
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+### 自动合并 value
+版本: >=1.28.0
+
+在多选(multiple=true)场景中,当我们选中祖先节点时,如果希望 value 不包含它对应的子孙节点,则可以通过 `autoMergeValue` 来设置,默认为 true。
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value: ['zhejiang','ningbo']
+        };
+    }
+    onChange(value) {
+        console.log(value);
+        this.setState({value});
+    }
+    render() {
+        const treeData = [
+            {
+                label: '浙江省',
+                value: 'zhejiang',
+                children: [
+                    {
+                        label: '杭州市',
+                        value: 'hangzhou',
+                        children: [
+                            {
+                                label: '西湖区',
+                                value: 'xihu',
+                            },
+                            {
+                                label: '萧山区',
+                                value: 'xiaoshan',
+                            },
+                            {
+                                label: '临安区',
+                                value: 'linan',
+                            },
+                        ],
+                    },
+                    {
+                        label: '宁波市',
+                        value: 'ningbo',
+                        children: [
+                            {
+                                label: '海曙区',
+                                value: 'haishu',
+                            },
+                            {
+                                label: '江北区',
+                                value: 'jiangbei',
+                            }
+                        ]
+                    },
+                ],
+            }
+        ];
+        return (
+            <Cascader
+                style={{ width: 300 }}
+                treeData={treeData}
+                placeholder="请选择所在地区"
+                value={this.state.value}
+                multiple
+                autoMergeValue={false}
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+### 动态更新数据
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Cascader, Button } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            treeData: [],
+        }
+        this.add = this.add.bind(this);
+    }
+    add() {
+        let itemLength = Math.floor(Math.random() * 3) + 1;
+        let treeData = new Array(itemLength).fill(0).map((v, i) => {
+            let length = Math.floor(Math.random() * 3);
+            let children = new Array(length).fill(0).map((cv, ci) => {
+                let child = {
+                    key: `${i}-${ci}`,
+                    label: `Item-${i}-${ci}`,
+                    value: `${i}-${ci}`
+                }
+                return child;
+            });
+            let item = {
+                key: `${i}`,
+                label: `Item-${i}`,
+                value: `${i}`,
+                children
+            };
+            return item;
+        })
+        this.setState({ treeData });
+    }
+    render() {
+        return (
+            <>
+                <Cascader
+                    style={{ width: 300 }}
+                    treeData={this.state.treeData}
+                    placeholder="请选择"
+                />
+                <br/>
+                <br/>
+                <Button onClick={this.add}>
+                    动态改变数据
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### 异步加载数据
+可以使用 loadData 实现异步加载数据
+**v>=1.8.0**  
+**不能与搜索同时使用**
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+    const initialData = [
+        {
+            label: 'Node1',
+            value: '0-0',
+        },
+        {
+            label: 'Node2',
+            value: '0-1',
+        },
+        {
+            label: 'Node3',
+            value: '0-2',
+            isLeaf: true
+        },
+    ];
+    const [data, setData] = useState(initialData);
+    
+    const updateTreeData = (list, value, children) => {
+        return list.map(node => {
+            if (node.value === value) {
+                return { ...node, children };
+            }
+            if (node.children) {
+                return { ...node, children: updateTreeData(node.children, value, children) };
+            }
+            return node;
+        });
+    }
+
+    const onLoadData = selectedOpt => {
+        const targetOpt = selectedOpt[selectedOpt.length - 1];
+        const { label, value } = targetOpt;
+        return new Promise(resolve => {
+            if (targetOpt.children) {
+                resolve();
+                return;
+            }
+
+            setTimeout(() => {
+                setData(origin =>
+                    updateTreeData(origin, value, [
+                        {
+                          label: `${label} - 1`,
+                          value: `${label}-1`,
+                          isLeaf: selectedOpt.length > 1
+                        },
+                        {
+                          label: `${label} - 2`,
+                          value: `${label}-2`,
+                          isLeaf: selectedOpt.length > 1
+                        },
+                      ]),
+                );
+                resolve();
+            }, 1000)
+        })
+    }
+
+    return (
+            <Cascader
+                style={{ width: 300 }}
+                treeData={data}
+                loadData={onLoadData}
+                placeholder="Please select"
+            />
+    );
+}
+```
+
+
+### 超长列表
+
+当你的数据结构层级特别深时,Cascader下拉菜单可能会超出屏幕,此时我们建议为下拉菜单设置 overflow-x: auto 以及一个合适的 width 宽度( 建议以N+0.5列的宽度为准,最右侧显示半列,以给用户一种右侧尚有待展开项,可以水平方向滚动的视觉暗示)
+
+```jsx live=true
+import React from 'react';
+import { Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'A',
+        value: 'A',
+        children: [
+            {
+                label: 'B',
+                value: 'B',
+                children: [
+                    {
+                        label: 'C',
+                        value: 'C',
+                        children: [
+                            {
+                                label: 'D',
+                                value: 'D',
+                                children: [
+                                    {
+                                        label: 'E',
+                                        value: 'E',
+                                        children: [
+                                            {
+                                                label: 'F',
+                                                value: 'F',
+                                            }
+                                        ]
+                                    }
+                                ]
+                            }
+                        ]
+                    }
+                ],
+            }
+        ]
+    }
+  ];
+  return (
+    <Cascader
+        dropdownClassName='components-cascader-demo'
+        style={{ width: 300 }}
+        treeData={treeData}
+        placeholder="请选择所在地区"
+    />
+  )
+}
+```
+
+```css
+.components-cascader-demo {
+    .semi-cascader-option-lists {
+        max-width: 510px;
+        overflow-x: auto;
+    }
+}
+```
+
+### 自定义 Trigger
+
+如果默认的触发器样式满足不了你的需求,可以用`triggerRender`自定义选择框的展示
+
+triggerRender 入参如下
+
+```typescript
+interface TriggerRenderProps {
+    /* Cascader 的 props */
+    componentProps: CascaderProps;
+    /* 是否禁用 Cascader */
+    disabled: boolean;
+    /**
+     * 单选时,已选中的 node 在 treeData 中的层级位置,如下例子,
+     * 当选中 浙江省-杭州市-萧山区时,此处 value 为 '0-0-0'
+     */
+    value?: string;
+    /* 当前 Input 框的输入值 */
+    inputValue: string;
+    /**
+     * 用于更新 input 框值的函数,当你在 triggerRender 自定义的
+     * Input 组件值更新时,你应该调用该函数,用于向 Cascader 内部
+     * 同步状态
+     */
+    onChange: (inputValue: string) => void;
+    /* 用于清空值的函数 */
+    onClear: () => void;
+    /* Placeholder */
+    placeholder?: string;
+}
+```
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { Cascader, Button } from '@douyinfe/semi-ui';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+            {
+                label: '浙江省',
+                value: 'zhejiang',
+                children: [
+                    {
+                        label: '杭州市',
+                        value: 'hangzhou',
+                        children: [
+                            {
+                                label: '西湖区',
+                                value: 'xihu',
+                            },
+                            {
+                                label: '萧山区',
+                                value: 'xiaoshan',
+                            },
+                            {
+                                label: '临安区',
+                                value: 'linan',
+                            },
+                        ],
+                    },
+                    {
+                        label: '宁波市',
+                        value: 'ningbo',
+                        children: [
+                            {
+                                label: '海曙区',
+                                value: 'haishu',
+                            },
+                            {
+                                label: '江北区',
+                                value: 'jiangbei',
+                            }
+                        ]
+                    },
+                ],
+            }
+        ], []);
+    const onChange = useCallback((val) => {
+        setValue(val);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setValue([]);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return value && value.length ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [value]);
+
+    const triggerRender = ({ value: innerStateValue, placeholder, ...rest }) => {
+        console.log(value)
+        console.log(rest)
+        return (
+            <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                {value && value.length ? value.join('/') : placeholder}
+            </Button>
+        );
+    };
+
+    return (
+        <Cascader
+            onChange={onChange}
+            value={value}
+            treeData={treeData}
+            placeholder='Custom Trigger'
+            triggerRender={triggerRender}
+        />
+    );
+}
+```
+
+## API 参考
+
+### Cascader
+
+| 属性               | 说明                                                                                 | 类型                                                                             | 默认值                           | 版本   |
+| ------------------ | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | -------------------------------- | ------ |
+| arrowIcon     |   自定义右侧下拉箭头 Icon,当 showClear 开关打开且当前有选中值时,hover 会优先显示 clear icon                                                              | ReactNode                                                                          |                             | 1.15.0      |
+| autoAdjustOverflow | 是否自动调整下拉框展开方向,用于边缘遮挡时自动调整展开方向 | boolean | true | - |
+| autoMergeValue | 设置自动合并 value。具体而言是,开启后,当某个父节点被选中时,value 将不包括该节点的子孙节点 | boolean | true |  1.28.0 |
+| bottomSlot | 底部插槽 | ReactNode | - |  1.27.0 |
+| changeOnSelect     | 是否允许选择非叶子节点                                                                   | boolean                                                                          | false                            | -      |
+| className          | 选择框的 className 属性                                                              | string                                                                           | -                                | -      |
+| defaultOpen       | 设置是否默认打开下拉菜单              | boolean   | false                                | -      |
+| defaultValue       | 指定默认选中的条目                                                                   | string\|number\|TreeNode\|(string\|number\|TreeNode)[]                                                                           | -                                | -      |
+| disabled           | 是否禁用                                                                             | boolean                                                                          | false                            | -      |
+| displayProp        | 设置回填选项显示的属性值                                                                 | string                                                                           | `label`                          | -      |
+| displayRender      | 设置回填格式                                                                 | (selected: string[] \| Entity, idx?: number) => ReactNode                                                        | selected => selected.join(' / ') | -      |
+| dropdownClassName  | 下拉菜单的 className 属性                                                            | string                                                                           | -                                | -      |
+| dropdownStyle      | 下拉菜单的样式                                                                       | object                                                                           | -                                | -      |
+| emptyContent       | 当搜索无结果时展示的内容                                                             | ReactNode                                                                        | `暂无数据`                       | -      |
+| filterLeafOnly       |  搜索结果是否只展示叶子结点路径   | boolean    | true    | 1.26.0    |
+| filterTreeNode     | 设置筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | ((inputValue: string, treeNodeString: string) => boolean) \| boolean | false                            | -      |
+| getPopupContainer | 指定父级 DOM,下拉框将会渲染至该 DOM 中,自定义需要设置 position: relative |() => HTMLElement|() => document.body|-|
+| insetLabel         | 前缀标签别名,主要用于 Form                                                          | ReactNode                                                                        | -                                | 0.28.0 |
+| loadData | 异步加载数据,需要返回一个Promise | (selectOptions: TreeNode[]) => Promise< void > |- |  1.8.0|
+| max| 多选时,限制多选选中的数量,超出 max 后将触发 onExceed 回调 | number |-|1.28.0|
+| maxTagCount| 多选时,标签的最大展示数量,超出后将以 +N 形式展示| number |-|1.28.0|
+| motion | 设置下拉框弹出的动画 |boolean\|object|true|-|
+| mouseEnterDelay | 鼠标移入后,延迟显示下拉框的时间,单位毫秒 | number | 50 | - |
+| mouseLeaveDelay | 鼠标移出后,延迟消失下拉框的时间,单位毫秒 | number | 50 | - |
+| multiple | 设置多选 | boolean | false |  1.28.0 |
+| placeholder        | 选择框默认文字                                                                       | string                                                                           | -                                | -      |
+| prefix             | 前缀标签                                                                             | ReactNode                                                                        | -                                | 0.28.0 |
+|restTagsPopoverProps |Popover 的配置属性,可以控制 position、zIndex、trigger 等,具体参考[Popover](/zh-CN/show/popover#API%20%E5%8F%82%E8%80%83)           |PopoverProps     | {}        |1.28.0|
+| searchPlaceholder  | 搜索框默认文字                                                                       | string                                                                           | -                                | -      |
+| showClear       |  是否展示清除按钮   | boolean    | false    | 0.35.0    |
+| showNext| 设置展开 Dropdown 子菜单的方式,可选: `click`、`hover` | string |`click`|1.29.0|
+| showRestTagsPopover| 当超过 maxTagCount,hover 到 +N 时,是否通过 Popover 显示剩余内容| boolean |false|1.28.0|
+| size               | 选择框大小,可选 `large`,`small`,`default`                                         | string                                                                           | `default`                        | -      |
+| stopPropagation | 是否阻止下拉框上的点击事件冒泡 | boolean | true | - |
+| disableStrictly | 设置是否开启严格禁用。开启后,当节点是 disabled 的时候,则不能通过子级或者父级的关系改变选中状态 | boolean | false | 1.32.0|
+| style              | 选择框的样式                                                                         | CSSProperties                                                                           | -                                | -      |
+| suffix             | 后缀标签                                                                             | ReactNode                                                                        | -                                | 0.28.0 |
+| topSlot | 顶部插槽 | ReactNode | - |  1.27.0 |
+| treeData           | 展示数据,具体属性参考 [TreeNode](#TreeNode)              | TreeNode[]                                                                  | \[]                              | -      |
+| treeNodeFilterProp | 搜索时输入项过滤对应的 treeNode 属性                                                 | string                                                                           | `label`                          | -      |
+| triggerRender | 自定义触发器渲染方法  | (triggerRenderData: object) => ReactNode | - | 0.34.0 |
+| validateStatus | trigger 的校验状态,仅影响展示样式。可选: default、error、warning | string | `default` | - |
+| value       | (受控)选中的条目                                                                   | string\|number\|TreeNode\|(string\|number\|TreeNode)[]                                                                           | -                                | -      |
+| zIndex | 下拉菜单的 zIndex | number | 1030 | - |
+| onBlur | 失焦 Cascader 的回调 | (e: MouseEvent) => void | - | - |
+| onChange           | 选中树节点时调用此函数,默认返回选中项 path 的 value 数组                            | (value: string\|number\|TreeNode\|(string\|number\|TreeNode)[]) => void                                                                         | -                                | -      |
+| onChangeWithObject | 是否将选中项 option 的其他属性作为回调。设为 true 时,onChange 的入参类型会从 string/number 变为 TreeNode。此时如果是受控,也需要把 value 设置成 TreeNode 类型,且必须含有 value 的键值,defaultValue 同理 | boolean | false | 1.16.0 |
+| onClear| showClear 为 true 时,点击清空按钮触发的回调 | () => void |-|1.29.0|
+| onDropdownVisibleChange       | 下拉框切换时的回调   | (visible: boolean) => void        | -                                | 0.35.0    |
+| onExceed| 多选时,超出 max 后触发的回调 | (checkedItem: Entity[]) => void |-|1.28.0|
+| onFocus| 聚焦 Cascader 的回调 | (e: MouseEvent) => void | - | - |
+| onListScroll | 下拉面板滚动的回调 | (e: React.Event, panel: { panelIndex: number; activeNode: TreeNode; } ) => void | - | 1.15.0 |
+| onLoad | 节点加载完毕时触发的回调 | (newLoadedKeys: Set< string >, data: TreeNode) => void |- |  1.8.0|
+| onSearch           | 文本框值变化时回调                                                                   | (value: string) => void                                                                         | -                                | -      |
+| onSelect           | 被选中时调用,返回选中项的 value                                                     | (value: string \| number \| (string \| number)[]) => void                                                                         | -                                | -      |
+
+### TreeNode
+
+| 属性      | 说明                  | 类型            | 默认值 |
+| -------- | --------------------- | -------------- | ----- |
+| children | 子节点                 | TreeNode[]     | -     |
+| disabled | 不可选状态 **>=0.35.0** | boolean        | -     |
+| isLeaf   | 叶子节点                | boolean        | -     |
+| label    | 展示的文本(必填)       | ReactNode       | -     |
+| loading  | 正在加载                | boolean        | -     |
+| value    | 属性值(必填)           | string\|number | -     |
+
+## 设计变量
+<DesignToken/>

+ 428 - 0
content/input/checkbox/index-en-US.md

@@ -0,0 +1,428 @@
+---
+localeCode: en-US
+order: 18
+category: Input
+title:  Checkbox
+subTitle: Checkbox
+icon: doc-checkbox
+brief: Checkboxes allow the user to select one or more items from a set.
+---
+
+
+## When to use
+
+-   When making multiple choices in a set of options;
+-   Use independenly to select from different states, similar to the Switch component. The difference is that switching the Switch triggers a state change directly, while Checkbox is generally used for tagging status and works with the submission.
+
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { Checkbox, CheckboxGroup } from '@douyinfe/semi-ui';
+```
+
+
+### Basic Usage
+
+When the Checkbox is used individually, you can control whether to check it through the `defaultChecked` and `checked` attributes.
+When `checked` is passed in, it is controlled component.
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <Checkbox onChange={checked => console.log(checked)}>
+    Semi Design
+  </Checkbox>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <Checkbox
+    defaultChecked
+    onChange={checked => console.log(checked)}
+  >
+    Semi Design
+  </Checkbox>
+)
+```
+
+You can use `extra` to add aextra information. The extra information usually is longer and even has line changes.
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+      <Checkbox
+        extra='Semi Design is a design system developed and maintained by IES Front-end Team and UED Team'
+      >
+        Semi Design
+      </Checkbox>
+      <br/>
+      <Checkbox
+        extra='Semi Design is a design system developed and maintained by IES Front-end Team and UED Team'
+        style={{ width: 400 }}
+      >
+        Semi Design
+      </Checkbox>
+    </>
+)
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <Checkbox Default Checked={false} with>UnChecked Disabled</Checkbox>
+    <br />
+    <Checkbox defaultChecked disabled>Checked Disabled</Checkbox>
+  </div>
+)
+```
+
+### Checkbox Group in JSX
+
+By placing the Checkbox element inside the CheckboxGroup, you can declare the Checkbox group
+Using the Checkbox group, you can more conveniently control the selection of a group of Checkboxes through the `defaultValue` and `value` properties of the CheckboxGroup
+At this time, Checkbox does not need to declare `defaultChecked` and `checked` attributes
+
+```jsx live=true
+import React from 'react';
+import { Checkbox, CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => (
+  <CheckboxGroup style={{ width: '100%' }} defaultValue={['A', 'B']}>
+    <Checkbox value="A">A</Checkbox>
+    <Checkbox value="B">B</Checkbox>
+    <Checkbox value="C">C</Checkbox>
+    <Checkbox value="D">D</Checkbox>
+    <Checkbox value="E">E</Checkbox>
+  </CheckboxGroup>
+)
+```
+
+
+### Checkbox Group in options
+
+You can pass an array using `options` to `CheckboxGroup` directly to generate a set of checkboxs.
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+
+  render() {
+    function onChange(checkedValues) {
+      console.log('checked = ', checkedValues);
+    }
+
+    const plainOptions = ['tiktok', 'vigo', 'helo'];
+    const options = [
+      { label: 'Aim for the highest', value: '1', extra: "Raise the bar. Wait for bigger gains. Find the best solutions by widening your perspective. Be attentive. Distill ideas down to their fundamental truths. Keep learning and growing" },
+      { label: 'Be grounded & courageous', value: '2', extra:"Make your own discoveries. Dive deep into facts. Stay level-headed. Focus on impact. Assume ownership, take risks, break the mold. Rapid iterations, multiple possibilities." },
+      { label: 'Be open & humble', value: '3', extra: "Trust yourself, trust each other. Be willing to offer and ask for help. Collaboration creates value. Approach problems with the big picture in mind. Be mindful and check your ego; stay open to different ideas." },
+      { label: 'Be candid & clear', value: '4', extra: "Dare to share your honest opinions. It's okay to make mistakes. Own it when you do. Stick to the facts, identify issues, and avoid \'leader-pleasing.\' Be accurate and forthright; be methodical and focused."}
+    ];
+    const optionsWithDisabled = [
+      { label: 'Photography', value: 'Photography' },
+      { label: 'Movies', value: 'Movies' },
+      { label: 'Running', value: 'Running', disabled: false },
+    ];
+    return (
+      <div>
+        <CheckboxGroup options={plainOptions} defaultValue={['tiktok']} onChange={onChange} />
+        <br/><br/>
+        <CheckboxGroup options={options} defaultValue={[]} onChange={onChange} />
+        <br/><br/>
+        <CheckboxGroup
+          options={optionsWithDisabled}
+          disabled
+          defaultValue={['Photography']}
+          onChange={onChange}
+        />
+      </div>
+    )
+  }
+}
+```
+
+### Layout Direction
+
+By setting `direction` to `horizontal` or `vertical`, You can adjust the layout within the Checkbox Group.
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => {
+  const options = [
+    { label: 'tiktok', value: 'tiktok' },
+    { label: 'hotsoon', value: 'hotsoon' },
+    { label: 'pipixia', value: 'pipixia' },
+    { label: 'toutiao', value: 'toutiao' }
+  ];
+  return (
+    <CheckboxGroup options={options} direction='horizontal' />
+  )
+}
+```
+
+### Controlled Component
+
+Used as a controlled component.
+
+```jsx live=true
+import React from 'react';
+import { Checkbox, Button } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+
+  constructor() {
+    super();
+    this.state = {
+      checked: true,
+      disabled: false,
+    }
+    this.toggleChecked = this.toggleChecked.bind(this);
+    this.toggleDisable = this.toggleDisable.bind(this);
+    this.onChange = this.onChange.bind(this);
+  }
+
+  toggleChecked () {
+    this.setState({ checked: !this.state.checked });
+  };
+
+  toggleDisable () {
+    this.setState({ disabled: !this.state.disabled });
+  };
+
+  onChange (e) {
+    console.log('checked = ', e.target.checked);
+    this.setState({
+      checked: e.target.checked,
+    });
+  };
+
+  render() {
+    const label = `${this.state.checked ? 'Checked' : 'Unchecked'} ${
+      this.state.disabled ? 'Disabled' : 'Enabled'
+    }`;
+    return (
+      <div>
+        <p style={{ marginBottom: '20px' }}>
+          <Checkbox
+            checked={this.state.checked}
+            disabled={this.state.disabled}
+            onChange={this.onChange}
+          >
+            {label}
+          </Checkbox>
+        </p>
+        <p>
+          <Button type="primary" size="small" onClick={this.toggleChecked}>
+            {!this.state.checked ? 'Check' : 'Uncheck'}
+          </Button>
+          <Button
+            style={{ marginLeft: '10px' }}
+            type="primary"
+            size="small"
+            onClick={this.toggleDisable}
+          >
+            {!this.state.disabled ? 'Disable' : 'Enable'}
+          </Button>
+        </p>
+      </div>
+    );
+  }
+}
+
+```
+
+### Checkbox State
+
+You may use the `indeterminate` property to set the state to indeterminate.
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Checkbox, CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => {
+    const plainOptions = ['Photography', 'Movies', 'Running'];
+    const [checkedList, setCheckedList] = useState(['Photography', 'Running']);
+    const [indeterminate, setIndeterminate] = useState(true);
+    const [checkAll, setCheckall] = useState(false);
+    const onChange = (checkedList) => {
+      setCheckedList(checkedList);
+      setIndeterminate(!!checkedList.length && checkedList.length < plainOptions.length);
+      setCheckall(checkedList.length === plainOptions.length);
+    }
+    const onCheckAllChange = (e) => {
+      console.log(e);
+      setCheckedList(e.target.checked ? plainOptions : []);
+      setIndeterminate(false);
+      setCheckall(e.target.checked);
+    }
+
+    return (
+        <div>
+          <div style={{ paddingBottom: 8, borderBottom: '1px solid var(--semi-color-border)' }}>
+            <Checkbox
+              indeterminate={indeterminate}
+              onChange={onCheckAllChange}
+              checked={checkAll}
+            >
+              Check all
+            </Checkbox>
+          </div>
+          <CheckboxGroup
+            style={{marginTop:6}}
+            options={plainOptions}
+            value={checkedList}
+            onChange={onChange}
+          />
+        </div>
+    )
+}
+
+```
+
+### Card Style
+
+version: >=1.30.0
+
+You can set `type='card'` to CheckboxGroup to realize card style with background.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { CheckboxGroup, Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+    <CheckboxGroup type='card' defaultValue={['1', '3']} direction='vertical'>
+        <Checkbox value={'1'} disabled extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+        <Checkbox value={'2'} disabled extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+        <Checkbox value={'3'} extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+        <Checkbox value={'4'} extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+    </CheckboxGroup>
+);
+```
+### Pure Card Style
+
+version: >=1.30.0
+
+You can set `type='pureCard'` to CheckboxGroup to realize a pure card style with background and no checkbox.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { CheckboxGroup, Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+    <CheckboxGroup type='pureCard' defaultValue={['1', '3']} direction='vertical'>
+        <Checkbox value={'1'} disabled extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+        <Checkbox value={'2'} extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+        <Checkbox value={'3'} extra='Checkbox Description' style={{width:280}}>
+            Checkbox Title
+        </Checkbox>
+    </CheckboxGroup>
+);
+```
+
+### Using with Grid
+
+Use `Checkbox.Group` with `Grid` to achieve flexible layouts.
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup, Checkbox, Row, Col } from '@douyinfe/semi-ui';
+
+() => (
+  <CheckboxGroup style={{ width: '100%' }}>
+    <Row>
+      <Col span={8}>
+        <Checkbox value="A">A</Checkbox>
+      </Col>
+      <Col span={8}>
+        <Checkbox value="B">B</Checkbox>
+      </Col>
+      <Col span={8}>
+        <Checkbox value="C">C</Checkbox>
+      </Col>
+      <Col span={8}>
+        <Checkbox value="D">D</Checkbox>
+      </Col>
+      <Col span={8}>
+        <Checkbox value="E">E</Checkbox>
+      </Col>
+    </Row>
+  </CheckboxGroup>
+)
+```
+
+## API Reference
+
+### Checkbox
+
+| PROPERTIES     | Instructions                                                 | type               | Default |
+| -------------- | ------------------------------------------------------------ | ------------------ | ------- |
+| checked        | Specify whether the current Checkbox is selected (it is invalid when used in Group)                     | boolean            | false   |
+| defaultChecked | Whether Checked by default (it is invalid when used in Group)                                           | boolean            | false   |
+| disabled       | Disabled state                                               | boolean            | false   |
+| extra          | Provide extra information <br/>**>= v0.25.0**                | reactNode          | -       |
+| value          | The value that the checkbox represents in the CheckboxGroup  | any | - |
+| indeterminate  | Set to indeterminate state, style control only               | boolean            | false   |
+| onChange       | Callback function when change                                | function(e: Event) | -       |
+
+### CheckboxGroup
+
+| PROPERTIES   | Instructions                                                            | type                   | Default    |
+| ------------ | ----------------------------------------------------------------------- | ---------------------- | ---------- |
+| defaultValue | Options selected by default                                             | string\string[]        | \[]        |
+| direction    | Layout of checkbox within a group, one of `vertical`, `horizontal`      | string                 | `vertical` |
+| disabled     | Disable the entire group                                                | boolean                | false      |
+| name         | The `name` attribute for all `input[type="checkbox"]` in Checkbox Group | string                 | -          |
+| options      | Specify optional                                                        | any\[]              | \[]        |
+| type         | Set the type of checkboxes, one of: `default`、`card`、`pureCard` **provided after v1.30.0**	| string        | `default`  |
+| value        | Specify selected options                                                | any\[]              | \[]        |
+| onChange     | Callback function when selected options change                          | function(checkedValue) | -          |
+
+### Method
+
+#### Checkbox
+
+| Name    | Description  |
+| ------- | ------------ |
+| blur()  | Remove focus |
+| focus() | Get focus    |
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+```material
+45, 64, 73, 89, 123
+``` -->

+ 413 - 0
content/input/checkbox/index.md

@@ -0,0 +1,413 @@
+---
+localeCode: zh-CN
+order: 18
+category: 输入类
+title: Checkbox 复选框
+icon: doc-checkbox
+brief: 复选框允许用户选中多个选项
+---
+
+
+## 何时使用
+
+- 在一组可选项中进行多项选择时;
+- 单独使用可以表示两种状态之间的切换,和 Switch 类似。区别在于切换 Switch 会直接触发状态改变,而 Checkbox 一般用于状态标记,需要和提交操作配合。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Checkbox, CheckboxGroup } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+Checkbox单个使用,可以通过`defaultChecked`、`checked`属性控制是否勾选。  
+当传入`checked`时,为受控使用。  
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <Checkbox onChange={checked => console.log(checked)}>Semi Design</Checkbox>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <Checkbox defaultChecked onChange={checked => console.log(checked)}>Semi Design</Checkbox>
+)
+```
+
+带辅助文本的checkbox。通过`extra`传入辅助文本。辅助文本会更长一些,甚至还可能换行。
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Checkbox extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统'>
+      Semi Design
+    </Checkbox>
+    <br/>
+    <Checkbox extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 400 }}>
+      Semi Design
+    </Checkbox>
+  </>
+)
+```
+
+### 禁用
+
+通过设置 `disabled` 属性,禁用 Checkbox
+
+```jsx live=true
+import React from 'react';
+import { Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+      <Checkbox defaultChecked={false} disabled>Unchecked Disabled</Checkbox>
+      <br />
+      <Checkbox defaultChecked disabled>Checked Disabled</Checkbox>
+  </div>
+)
+```
+
+### JSX方式声明Checkbox组
+
+通过在CheckboxGroup内部放置 Checkbox元素,可以声明Checkbox组  
+使用Checkbox组,你可以更便捷地通过CheckboxGroup的`defaultValue`、`value`属性去控制一组Checkbox的选中与否
+此时Checkbox不需要再声明`defaultChecked`、`checked`属性
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup, Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+  <CheckboxGroup style={{ width: '100%' }} defaultValue={['A', 'B']}>
+      <Checkbox value="A">A</Checkbox>
+      <Checkbox value="B">B</Checkbox>
+      <Checkbox value="C">C</Checkbox>
+      <Checkbox value="D">D</Checkbox>
+      <Checkbox value="E">E</Checkbox>
+  </CheckboxGroup>
+)
+```
+
+
+### 数组方式声明 Checkbox 组
+
+也可以将数组通过 `options` 属性直接传入 CheckboxGroup,直接生成 Checkbox 组
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => {
+  function onChange(checkedValues) {
+    console.log('checked = ', checkedValues);
+  }
+
+  const plainOptions = ['抖音', '火山', '皮皮虾'];
+  const options = [
+    { label: '追求极致', value: '1', extra: '不断提高要求,延迟满足感,在更大范围里找最优解' },
+    { label: '务实敢为', value: '2', extra:'直接体验,深入事实;不自嗨,注重效果;能突破有担当,打破定式;尝试多种可能,快速迭代' },
+    { label: '开放谦逊', value: '3', extra: '内心阳光,信任伙伴;乐于助人和求助,合作成大事;格局大,上个台阶想问题;对外敏锐谦虚,ego小,听得进意见' },
+    { label: '坦诚清晰', value: '4', extra: '敢当面表达真实想法;能承认错误,不装不爱面子;实事求是,暴露问题,反对“向上管理”;准确、简洁、直接,有条理有重点'}
+  ];
+  const optionsWithDisabled = [
+    { label: 'Photography', value: 'Photography' },
+    { label: 'Movies', value: 'Movies' },
+    { label: 'Running', value: 'Running', disabled: false },
+  ];
+  return (
+    <div>
+      <CheckboxGroup options={plainOptions} defaultValue={['抖音']} onChange={onChange} />
+      <br/><br/>
+      <CheckboxGroup options={options} defaultValue={[]} onChange={onChange} />
+      <br/><br/>
+      <CheckboxGroup
+        options={optionsWithDisabled}
+        disabled
+        defaultValue={['Photography']}
+        onChange={onChange}
+      />
+  </div>
+  )
+}
+```
+
+
+### 水平排列
+
+通过设置 `direction` 为 `horizontal` 或者 `vertical` 可以调整 CheckboxGroup 内的布局
+
+```jsx live=true
+import React from 'react';
+import { CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => {
+  const options = [
+    { label: '抖音', value: 'tiktok' },
+    { label: '火山', value: 'hotsoon' },
+    { label: '皮皮虾', value: 'pipixia' },
+    { label: '今日头条', value: 'toutiao' }
+  ];
+  return (
+    <CheckboxGroup options={options} direction='horizontal' />
+  )
+}
+```
+
+
+### 受控
+
+联动 checkbox。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Checkbox, Button } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+
+  constructor() {
+    super();
+    this.state = {
+      checked: true,
+      disabled: false,
+    }
+    this.toggleChecked = this.toggleChecked.bind(this);
+    this.toggleDisable = this.toggleDisable.bind(this);
+    this.onChange = this.onChange.bind(this);
+  }
+
+  toggleChecked () {
+    this.setState({ checked: !this.state.checked });
+  };
+
+  toggleDisable () {
+    this.setState({ disabled: !this.state.disabled });
+  };
+
+  onChange (e) {
+    console.log('checked = ', e.target.checked);
+    this.setState({
+      checked: e.target.checked,
+    });
+  };
+
+  render() {
+    const label = `${this.state.checked ? 'Checked' : 'Unchecked'} ${
+      this.state.disabled ? 'Disabled' : 'Enabled'
+    }`;
+    return (
+      <div>
+        <p style={{ marginBottom: '20px' }}>
+          <Checkbox
+            checked={this.state.checked}
+            disabled={this.state.disabled}
+            onChange={this.onChange}
+          >
+            {label}
+          </Checkbox>
+        </p>
+        <p>
+          <Button type="primary" size="small" onClick={this.toggleChecked}>
+            {!this.state.checked ? 'Check' : 'Uncheck'}
+          </Button>
+          <Button
+            style={{ marginLeft: '10px' }}
+            type="primary"
+            size="small"
+            onClick={this.toggleDisable}
+          >
+            {!this.state.disabled ? 'Disable' : 'Enable'}
+          </Button>
+        </p>
+      </div>
+    );
+  }
+}
+
+```
+
+### 全选
+
+在实现全选效果时,你可能会用到 `indeterminate` 属性。
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Checkbox, CheckboxGroup } from '@douyinfe/semi-ui';
+
+() => {
+    const plainOptions = ['Photography', 'Movies', 'Running'];
+    const [checkedList, setCheckedList] = useState(['Photography', 'Running']);
+    const [indeterminate, setIndeterminate] = useState(true);
+    const [checkAll, setCheckall] = useState(false);
+    const onChange = (checkedList) => {
+      setCheckedList(checkedList);
+      setIndeterminate(!!checkedList.length && checkedList.length < plainOptions.length);
+      setCheckall(checkedList.length === plainOptions.length);
+    }
+    const onCheckAllChange = (e) => {
+      console.log(e);
+      setCheckedList(e.target.checked ? plainOptions : []);
+      setIndeterminate(false);
+      setCheckall(e.target.checked);
+    }
+
+    return (
+        <div>
+          <div style={{ paddingBottom: 8, borderBottom: '1px solid var(--semi-color-border)' }}>
+            <Checkbox
+              indeterminate={indeterminate}
+              onChange={onCheckAllChange}
+              checked={checkAll}
+            >
+              Check all
+            </Checkbox>
+          </div>
+          <CheckboxGroup
+            style={{marginTop:6}}
+            options={plainOptions}
+            value={checkedList}
+            onChange={onChange}
+          />
+        </div>
+    )
+}
+```
+
+### 卡片样式
+
+version: >=1.30.0
+
+可以给 CheckboxGroup 设置 `type='card'`,实现带有背景的卡片样式。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { CheckboxGroup, Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+    <CheckboxGroup type='card' defaultValue={['1', '3']} direction='vertical'>
+        <Checkbox value={'1'} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+        <Checkbox value={'2'} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+        <Checkbox value={'3'} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+        <Checkbox value={'4'} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+    </CheckboxGroup>
+);
+```
+### 无 checkbox 的纯卡片样式
+
+version: >=1.30.0
+
+可以给 CheckboxGroup 设置 `type='pureCard'`,实现带有背景且无 checkbox 的纯卡片样式。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { CheckboxGroup, Checkbox } from '@douyinfe/semi-ui';
+
+() => (
+    <CheckboxGroup type='pureCard' defaultValue={['1', '3']} direction='vertical'>
+        <Checkbox value={'1'} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+        <Checkbox value={'2'} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+        <Checkbox value={'3'} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Checkbox>
+    </CheckboxGroup>
+);
+```
+
+### 配合grid布局
+
+Checkbox.Group 内嵌 Checkbox 并与 Grid 组件一起使用,可以实现灵活的布局。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Checkbox, CheckboxGroup, Row, Col } from '@douyinfe/semi-ui';
+
+() => (
+  <CheckboxGroup style={{ width: '100%' }}>
+      <Row>
+        <Col span={8}>
+          <Checkbox value="A">A</Checkbox>
+        </Col>
+        <Col span={8}>
+          <Checkbox value="B">B</Checkbox>
+        </Col>
+        <Col span={8}>
+          <Checkbox value="C">C</Checkbox>
+        </Col>
+        <Col span={8}>
+          <Checkbox value="D">D</Checkbox>
+        </Col>
+        <Col span={8}>
+          <Checkbox value="E">E</Checkbox>
+        </Col>
+      </Row>
+  </CheckboxGroup>
+)
+```
+
+## API参考
+
+### Checkbox
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| checked | 指定当前Checkbox是否选中(在Group中使用时无效) | boolean | false |
+| defaultChecked | 初始是否选中(在Group中使用时无效) | boolean | false |
+| disabled | 失效状态 | boolean | false |
+| extra | 副文本<br/>__v0.25.0后提供__ | reactNode | - |
+| value | 该checkbox在CheckboxGroup中代表的value | any | - |
+| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false |
+| onChange | 变化时回调函数 | function(e:Event) | - |
+
+### Checkbox Group
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| defaultValue | 组内默认选中的选项,会与Checkbox的value值做匹配 | any\[] | \[] |
+| direction | 组内checkbox布局,可选水平```horizontal```或```vertical``` | string | `vertical` |
+| disabled | 整组失效 | boolean | false |
+| name | CheckboxGroup 下所有 `input[type="checkbox"]` 的 `name` 属性 | string | - |
+| options | 指定可选项 | any\[] | \[] |
+| type |	设置所有 checkbox 的样式类型,可选值为: `default`、`card`、`pureCard` **v1.30.0 后提供**|string|`default`|
+| value | 指定选中的选项 | any\[] | \[] |
+| onChange | 变化时回调函数 | function(checkedValue) | - |
+
+### 方法
+
+#### Checkbox
+
+| 名称 | 描述 |
+| --- | --- |
+| blur() | 移除焦点 |
+| focus() | 获取焦点 |
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+```material
+45, 64, 73, 89, 123
+``` -->

+ 823 - 0
content/input/datepicker/index-en-US.md

@@ -0,0 +1,823 @@
+---
+localeCode: en-US
+order: 19
+category: Input
+title: DatePicker
+subTitle: Date Selector
+icon: doc-datepicker
+brief: The date selector is used to help the user select a compliant, formatted date (time) or date (time) range.
+---
+
+## When to Use
+
+When the user needs to enter a date, you can click on the standard input box and pop up the date panel to select.
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { DatePicker } from '@douyinfe/semi-ui';
+```
+
+
+### Basic Use
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker onChange={(date, dateString) => console.log(dateString)} style={{ width: 240 }} />;
+    }
+}
+```
+
+### Picker Density
+
+The density can be used to control the size of the picker panel. The `compact` is the small size and the `default` is the default size. Support after v1.17.0.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return (
+      <div>
+        <DatePicker type="dateTime" density='compact' /><br /><br />
+        <DatePicker type="dateRange" density='compact' style={{ width: 260 }} />
+      </div>
+  );
+}
+```
+
+### With an Embedded Label
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <DatePicker insetLabel="End date" style={{ width: 240 }} />;
+}
+```
+
+### Multiple Date Selection
+
+Set `Multiple` to `true`, can choose multiple dates.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker multiple={true} style={{ width: 240 }} />;
+    }
+}
+```
+
+### Date and Time Selection
+
+Set `type` to `dateTime`, can choose date and time.  
+If you want to remove the infinite loop scrolling interaction of TimePicker, you can pass timePickerOpts into a specific configuration to close it.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return (
+            <>
+                <h4>Default date and time selection</h4>
+                <DatePicker type="dateTime" />
+                <br />
+                <br />
+                <h4>Turn off cycled mode</h4>
+                <DatePicker type="dateTime" timePickerOpts={{ scrollItemProps: { cycled: false } }} />
+            </>
+        );
+    }
+}
+```
+
+### Date Range Selection
+
+Set `type` to `dateRange`, can choose the date range.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker type="dateRange" style={{ width: 260 }} onChange={console.log} />;
+    }
+}
+```
+
+<Notice type="primary" title="Note">
+    <div>When you use range selection, if only one date is selected, onChange will not be triggered at this time. Only when both the start date and the end date are selected will onChange be triggered.</div>
+</Notice>
+
+### Date Time Range Selection
+
+Set `type` to `dateTimeRange`, can choose the date range and choose time;
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker type="dateTimeRange" style={{ width: 380 }} onChange={console.log} />;
+    }
+}
+```
+
+### Synchronously switch months
+
+version:>= 1.28.0
+
+In the scenario of range selection, turning on `syncSwitchMonth` means to switch the two panels simultaneously. The default is false.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return (
+            <DatePicker
+                syncSwitchMonth={true}
+                type="dateTimeRange"
+                style={{ width: 380 }}
+            />
+        );
+    }
+}
+```
+
+### Panel Change Callback
+
+version:>=1.28.0
+
+`onPanelChange` will be called when the month or year of the panel is changed.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return (
+            <DatePicker
+                syncSwitchMonth={true}
+                type="dateTimeRange"
+                style={{ width: 380 }}
+                onPanelChange={(date, dateString) => console.log(date, dateString)}
+            />
+        );
+    }
+}
+```
+
+### Select Week
+
+`daterange` is used with `startDateOffset` and `endDateOffset` to select range with single click, such as weekly selection and biweekly selection. Support after v1.10.0.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const handleChange = date => {
+        console.log('date changed', date);
+    };
+
+    return (
+        <div>
+            <h4>Choose a week</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                startDateOffset={date => dateFns.startOfWeek(date, { weekStartsOn: 1 })}
+                endDateOffset={date => dateFns.endOfWeek(date, { weekStartsOn: 1 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+            <h4>Choose two weeks</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                startDateOffset={date => dateFns.startOfWeek(date, { weekStartsOn: 1 })}
+                endDateOffset={date => dateFns.add(dateFns.endOfWeek(date, { weekStartsOn: 1 }), { days: 7 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+            <h4>Select the current day and the next 6 days</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                endDateOffset={date => dateFns.add(date, { days: 6 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+        </div>
+    );
+}
+```
+
+### Selection
+
+**Version:** > = 0.21.0
+
+Set `type` to `month`, can make year-to-month selection.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker defaultValue={new Date()} type="month" style={{ width: 140 }} />;
+    }
+}
+```
+
+### Confirm Date and Time Selection
+
+**Version: > = 0.18.0**
+
+For the selection of "datetime" (type = "dateTime") or "datetime range" (type = "dateTimeRange"), you can confirm it before writing the value into the input box. You can pass `NeedConfirm` = true to enable this behavior.
+
+At the same time, the click callbacks of the "onConfirm" and "onCancel" buttons are supported.
+
+The following example binds three callbacks: `onChange`, `onConfirm` and `onCancel`, and you can open the console to see the difference in print information.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return (
+            <DatePicker
+                type="dateTime"
+                needConfirm={true}
+                onConfirm={(...args) => {
+                    console.log('Confirmed: ', ...args);
+                }}
+                onCancel={(...args) => {
+                    console.log('Canceled: ', ...args);
+                }}
+                onChange={(...args) => {
+                    console.log('Changed: ', ...args);
+                }}
+            />
+        );
+    }
+}
+```
+
+### Date and Time Selection with Shortcuts
+
+Pass parameter `Presets` to set shortcuts for date selection.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        this.presets = [
+            {
+                text: 'Today',
+                start: new Date(),
+                end: new Date(),
+            },
+            () => ({
+                text: 'Tomorrow',
+                start: new Date(new Date().valueOf() + 1000 * 3600 * 24),
+                end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
+            }),
+        ];
+    }
+
+    render() {
+        return <DatePicker type="dateTime" presets={this.presets} />;
+    }
+}
+```
+
+### Render TopSlot/BottomSlot
+
+With `topSlot` and `bottomSlot`, you can customize the rendering of the top and bottom extra areas.
+
+```jsx live=true
+import React, { useState, useMemo } from 'react';
+import { DatePicker, Typography, Tabs, TabPane, Space } from '@douyinfe/semi-ui';
+import { IconBulb } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const { Text } = Typography;
+
+    const [activeTab, setActiveTab] = useState('1');
+    const [date, setDate] = useState();
+    const uedDisabledDate = currentDate => currentDate && currentDate.getDate() > 10 && currentDate.getDate() < 15;
+    const testDisabledDate = currentDate => currentDate && currentDate.getDate() > 15 && currentDate.getDate() < 25;
+
+    const handleTabChange = tab => {
+        setActiveTab(tab);
+        setDate();
+    };
+
+    const handleDateChange = value => {
+        setDate(value);
+    };
+
+    const disabledDate = useMemo(() => (activeTab === '1' ? uedDisabledDate : testDisabledDate), [activeTab]);
+
+    const TopSlot = function (props) {
+        const { style } = props;
+        return (
+            <Tabs size="small" onChange={handleTabChange} activeKey={activeTab} style={{ padding: '12px 20px 0', ...style }}>
+                <TabPane tab="UED Schedule" itemKey="1" />
+                <TabPane tab="Test schedule" itemKey="2" />
+            </Tabs>
+        );
+    };
+
+    const BottomSlot = function (props) {
+        const { style } = props;
+        return (
+            <Space style={{ padding: '12px 20px', ...style }}>
+                <IconBulb style={{ color: 'rgba(var(--semi-amber-5), 1)' }} />
+                <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
+                    Please read before finalizing
+                </Text>
+                <Text link={{ href: 'https://semi.design/', target: '_blank' }}>Release notice</Text>
+            </Space>
+        );
+    };
+
+    const MonthBottomSlot = function (props) {
+        const { style } = props;
+        return (
+            <Space style={{ padding: '12px 20px', ...style }}>
+                <IconBulb style={{ color: 'rgba(var(--semi-amber-5), 1)' }} />
+                <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
+                    please read
+                </Text>
+                <Text link={{ href: 'https://semi.design/', target: '_blank' }}>Notice</Text>
+            </Space>
+        );
+    };
+
+    return (
+        <div>
+            <DatePicker 
+                topSlot={<TopSlot />}
+                disabledDate={disabledDate}
+                value={date}
+                onChange={handleDateChange}
+                dropdownClassName="components-datepicker-demo-slot"
+                placeholder="Please select a schedule"
+            />
+            <br /><br />
+            <DatePicker
+                bottomSlot={<BottomSlot />}
+                placeholder="Please select release time"
+            />
+            <br /><br />
+            <DatePicker
+                type="month"
+                bottomSlot={<MonthBottomSlot />}
+                placeholder="Please select month"
+            />
+            <br /><br />
+            <DatePicker 
+                topSlot={<TopSlot style={{ padding: '8px 12px 0' }} />} 
+                bottomSlot={<BottomSlot style={{ padding: '8px 12px' }} />} 
+                density="compact"
+                dropdownClassName="components-datepicker-demo-slot"
+            />
+            <br /><br />
+            <DatePicker 
+                type="dateTimeRange"
+                bottomSlot={<BottomSlot />}
+                style={{ width: 380 }}
+                placeholder="Please select a time range"
+            />
+        </div>
+    );
+}
+```
+
+```css
+.components-datepicker-demo-slot {
+    
+    .semi-tabs-content {
+        padding: 0;
+    }
+    
+    .semi-tabs-bar-line.semi-tabs-bar-top {
+        border-bottom: none;
+    }
+}
+```
+
+### Disable Date Selection
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker disabled type="dateTime" defaultValue={new Date()} />;
+    }
+}
+```
+
+### Disable Partial Date or Time
+
+Pass in `disabledDate` to disable the specified date, pass in `disabledTime` to disable the specified time, and with `defaultPickerValue` you can specify the year and month when the panel is opened.
+
+`disabledDate` and`disabledTime`, the accepted input parameters are the current date, the former returns a `boolean` value, the latter returns an [object](/en-US/input/timepicker#API_Reference) It will be directly passed to the `TimePicker` component.
+
+<Notice type="primary" title="Note">
+    <div>When you use timeZone, the Date of the first parameter is the time under the time zone you choose (similar to the first return value of onChange)</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import * as dateFns from 'date-fns';
+import { range } from 'lodash-es';
+
+class App extends React.Component {
+    constructor(props = {}) {
+        super(props);
+
+        this.today = () => new Date();
+
+        this.nextValidMonth = () => {
+            const nextValidDate = this.today();
+            nextValidDate.setMonth((nextValidDate.getMonth() + 1) % 12);
+            return nextValidDate;
+        };
+
+        this.disabledTime = date =>
+            dateFns.isToday(date)
+                ? {
+                      disabledHours: () => [17, 18],
+                      disabledMinutes: hour => (19 === hour ? range(0, 10, 1) : []),
+                      disabledSeconds: (hour, minute) => (hour === 20 && minute === 20 ? range(0, 20, 1) : []),
+                  }
+                : null;
+
+        this.disabledTime2 = (date, panelType) => {
+            if (panelType === 'left') {
+                return { disabledHours: () => [17, 18] };
+            } else {
+                return { disabledHours: () => [12, 13, 14, 15, 16, 17, 18] };
+            }
+        };
+
+        this.disabledDate = date => {
+            const deadDate = this.today();
+            const month = deadDate.getMonth();
+            deadDate.setDate(28);
+            deadDate.setMonth((month + 1) % 12);
+            return date.getTime() < deadDate.getTime();
+        };
+    }
+
+    render() {
+        return (
+            <div>
+                <div>
+                    <h4>Disabled 17:00:00-18:00:00 today</h4>
+                    <DatePicker type="dateTime" hideDisabledOptions={false} disabledTime={this.disabledTime} />
+                </div>
+                <div>
+                    <h4>Two panels disable different times</h4>
+                    <DatePicker
+                        type="dateTimeRange"
+                        hideDisabledOptions={false}
+                        disabledTime={this.disabledTime2}
+                        style={{ width: 380 }}
+                    />
+                </div>
+                <div>
+                    <h4>Disable time before the 28th of next month</h4>
+                    <DatePicker
+                        type="dateTimeRange"
+                        disabledDate={this.disabledDate}
+                        defaultPickerValue={this.nextValidMonth()}
+                        style={{ width: 380 }}
+                    />
+                </div>
+            </div>
+        );
+    }
+}
+```
+
+When `type` contains `range`, the date can be disabled dynamically according to the rangeStart. The `options` parameter is supported after 1.9.0
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import * as dateFns from 'date-fns';
+
+class App extends React.Component {
+    render() {
+        return (
+            <div>
+                <h4>Prohibit selection of previous dates</h4>
+                <DatePicker
+                    type={'dateRange'}
+                    disabledDate={(date, options) => {
+                        const { rangeStart } = options;
+                        const startDate = dateFns.parseISO(rangeStart);
+                        return dateFns.isBefore(date, startDate);
+                    }}
+                    style={{ width: 260 }}
+                />
+            </div>
+        );
+    }
+}
+```
+
+### Custom Display Format
+
+Pass parameter `format` to custom display format.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    render() {
+        return <DatePicker format="yyyy-MM-dd HH:mm" type="dateTime" defaultValue={new Date()} />;
+    }
+}
+```
+
+### Custom Trigger
+
+**Version:** >=0.34.0
+
+By default we use the `Input` component as the trigger for the `DatePicker` component. You can customize this trigger by passing the `triggerRender` method.
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import * as dateFns from 'date-fns';
+import { DatePicker, Button } from '@douyinfe/semi-ui';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const [date, setDate] = useState(new Date());
+    const formatToken = 'yyyy-MM-dd';
+    const onChange = useCallback(date => {
+        setDate(date);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setDate(null);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return date ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [date]);
+
+    return (
+        <DatePicker
+            onChange={onChange}
+            value={date}
+            format={formatToken}
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                    {(date && dateFns.format(date, formatToken)) || placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+### Custom Render Date Content
+
+**Version:**>=1.4.0
+
+`renderDate: (dayNumber: number, fullDate: string) => ReactNode`
+
+-   `dayNumber`: such as `13`.
+-   `fullDate`: such as `2020-08-13`.
+
+```jsx live=true
+import React from 'react';
+import { DatePicker, Tooltip } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const dateStyle = {
+        width: '100%',
+        height: '100%',
+        border: '1px solid var(--semi-color-primary)',
+        display: 'flex',
+        justifyContent: 'center',
+        alignItems: 'center',
+    };
+    const renderDate = (dayNumber, fullDate) => {
+        if (dayNumber === 1) {
+            return (
+                <Tooltip content={'Always Day 1'}>
+                    <div style={dateStyle}>
+                        {dayNumber}
+                    </div>
+                </Tooltip>
+            );
+        }
+        return dayNumber;
+    };
+    return <DatePicker renderDate={renderDate} />;
+}
+```
+
+### Custom Render Date Box
+
+**Version:**>=1.4.0
+
+`renderFullDate: (dayNumber: number, fullDate: string, dayStatus: object) => ReactNode`
+
+`dayStatus` is this status of current date box. The included keys are as follows.
+
+```tsx
+type DayStatusType = {
+    isToday?: boolean,
+    isSelected?: boolean,
+    isDisabled?: boolean,
+    isSelectedStart?: boolean,
+    isSelectedEnd?: boolean,
+    isInRange?: boolean,
+    isHover?: boolean,
+    isOffsetRangeStart?: boolean,
+    isOffsetRangeEnd?: boolean,
+    isHoverInOffsetRange?: boolean,
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import classNames from 'classnames';
+
+function Demo() {
+    const renderFullDate = (dayNumber, fullDate, dayStatus) => {
+        const { isInRange, isHover, isSelected, isSelectedStart, isSelectedEnd } = dayStatus;
+        const prefix = 'components-datepicker-demo';
+
+        const dateCls = classNames({
+            [`${prefix}-day-inrange`]: isInRange,
+            [`${prefix}-day-hover`]: isHover,
+            [`${prefix}-day-selected`]: isSelected,
+            [`${prefix}-day-selected-start`]: isSelectedStart,
+            [`${prefix}-day-selected-end`]: isSelectedEnd,
+        });
+
+        const dayStyle = {
+            display: 'flex',
+            alignItems: 'center',
+            justifyContent: 'center',
+            width: '80%',
+            height: '80%',
+            borderRadius: '50%',
+        };
+
+        return (
+            <div style={dayStyle} className={dateCls}>
+                {dayNumber}
+            </div>
+        );
+    };
+
+    return <DatePicker style={{ width: 260 }} type={'dateRange'} renderFullDate={renderFullDate} />;
+}
+```
+
+```css
+.components-datepicker-demo-day-inrange,
+.components-datepicker-demo-day-hover {
+    background: var(--semi-color-primary-light-hover);
+}
+
+.components-datepicker-demo-day-selected,
+.components-datepicker-demo-day-selected-start,
+.components-datepicker-demo-day-selected-end {
+    color: var(--semi-color-bg-2);
+    background: var(--semi-color-primary);
+}
+```
+
+## API Reference
+
+| Properties         | Instructions                                                                                                                                                                              | Type                                             | Default | Version    |
+|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|---------|------------|
+| autoAdjustOverflow | Whether the floating layer automatically adjusts its direction when it is blocked                                                                                                         | boolean                                          | true    | **0.34.0** |
+| autoFocus          | Automatic access to focus                                                                                                                                                                 | boolean                                          | false   | **1.10.0** |
+| autoSwitchDate     | When false is passed in, the date will not be automatically switched when the year and year are changed through the left and right buttons on the top of the panel and the drop-down menu | boolean                                          | true    | **1.13.0** |
+| bottomSlot         | Render the bottom extra area                                                                                                                                                              | ReactNode                                        |         | **1.22.0** |
+| className          | Class name                                                                                                                                                                                | string                                           | -       |            |
+| defaultOpen        | Panel displays or hides by default                                                                                                                                                        | boolean                                          | false   |            |
+| defaultPickerValue | Default panel date                                                                                                                                                                        | string\|Date\|number\|string[]\|Date[]\|number[] |         |            |
+| defaultValue       | Default                                                                                                                                                                                   | string                                                                                                                                                                                                    | Date\|number\|string[]\|Date[]\|number[]                                              |                           |  |
+| density            | Density of picker panel, one of `default`, `compact`                                                                 | string                                                                                                                                                                                                    | default                                        | **1.17.0**              |
+| disabled           | Is it disabled?                                                                                                                                                                           | boolean                                                                                                                                                                                                   | false                                                                                 |                           |
+| disabledDate       | The date is prohibited from the judgment method, and the date is prohibited when returned to true. Options parameter supported after 1.9.0 and rangeEnd supported after 1.29            | (date: Date, options: { rangeStart: string, rangeEnd: string }) => boolean                                                                                                                                                  | () = > false                                                                          |                           |
+| disabledTime       | Time prohibition configuration, the return value will be transparently passed to [`TimePicker`](/en-US/input/timepicker#API_Reference) as a parameter                                | (date: Date \| Date[], panelType?: string) => ({ <br/>disabledHours:() => number[], <br/>disabledMinutes: (hour: number) => number[], <br/>disabledSeconds: (hour: number, minute: number) => number[] }) | () => false                                                                           | **0.36.0**                |
+| disabledTimePicker | Disable time selection or not.                                                                                                                                                            | boolean                                                                                                                                                                                                   |                                                                                       | **0.32.0**                |
+| dropdownClassName  | CSS classname for drop-down menu                                                                                                                                                          | string                                                               |                                 | **1.13.0** |
+| dropdownStyle      | Inline style of drop-down menu                                                                                                                                                           | object                                                               |                                  | **1.13.0** |
+| endDateOffset      | When type is dateRange, set the end date of the selected range                                                                                                                            | (selectedDate?: Date) => Date;                                                                                                                                                                            | -                                                                                     | **1.10.0**                |
+| format             | Date string format displayed in the input box                                                                                                                                             | string                                                                                                                                                                                                    | Corresponding to type: For details, see [Date and Time Format](#Date%20and%20Time%20Format) |                           |
+| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | function():HTMLElement | () = > document.body |
+| inputReadOnly      | Is the text box readonly                                                                                                                                                                  | boolean                                                                                                                                                                                                   | false                                                                                 |                           |
+| inputStyle         | Input box style                                                                                                                                                                           | object                                                                                                                                                                                                    |                                                                                       |                           |
+| insetLabel         | Prefix label, lower priority than `prefix`                                                                                                                                                | string\|ReactNode                                                                                                                                                                                         |                                                                                       |                           |
+| max                | When multiple is set to true, the number of selected, non-pass or value is null\|undefined, unlimited.                                                                                     | number                                                                                                                                                                                                    | -                                                                                     |                           |
+| multiple           | Whether you can choose multiple, only type = "date" is supported                                                                                                                          | boolean                                                                                                                                                                                                   | false                                                                                 |                           |
+| needConfirm        | Do you need to "confirm selection", only `type= "dateTime"|"dateTimeRange"` works.                                                                                                        | boolean                                                                                                                                                                                                   |                                                                                       | **0.18.0**                |
+| open               | Controlled properties displayed or hidden by panels                                                                                                                                       | boolean                                                                                                                                                                                                   |                                                                                       |                           |
+| placeholder        | Input box prompts text                                                                                                                                                                    | string                                                                                                                                                                                                    | 'Select date'                                                                         |                           |
+| position           | Floating layer position, optional value with [Popover #API Reference · position](/en-US/show/popover#API%20Reference)                                                                 | string                                                                                                                                                                                                    | 'bottomLeft'                                                                          |                           |
+| prefix             | Prefix content                                                                                                                                                                            | string\|ReactNode                                                                                                                                                                                         |                                                                                       |                           |
+| presets            | Date Time Shortcut                                                                                                                                                                        | Array < {start: string\|Date\|number, end: string\|Date\|number, text: string}\| function(): {start: string\|Date\|number, end: string\|Date\|number, text: string} >                                     | []                                                                                    |                           |
+| rangeSeparator     | Custom range type picker separator of input trigger | string | '~' | **1.31.0** 
+| renderDate         | Custom date display content                                                                                                                                                               | (dayNumber, fullDate) => ReactNode                                                                                                                                                                        | -                                                                                     | **1.4.0**            |
+| renderFullDate     | Custom display date box                                                                                                                                                                   | (dayNumber, fullDate, dayStatus) => ReactNode                                                                                                                                                             | -                                                                                     | **1.4.0**            |
+| showClear          | Do you show the clear button?                                                                                                                                        | boolean                                                                                                                                                                                                   | true                                                                                  |        **0.35.0**                           |
+| size               | Size, optional: "small," "default," "large"                                                                                                                                               | string                                                                                                                                                                                                    | 'default'                                                                             |                           |
+| spacing            | The distance between the pop-up layer and the children element                                                                                                                            | number                                                                                                                                                                                                    | 4                                                                                     | **1.9.0**                 |
+| startDateOffset    | When type is dateRange, set the start date of the selected range                                                                                                                          | (selectedDate?: Date) => Date;                                                                                                                                                                            | -                                                                                     | **1.10.0**                |
+| syncSwitchMonth    | In the scene of range, it supports synchronous switching of the month of the dual panel|boolean|false|**1.28.0**|
+| timePickerOpts     | For other parameters that can be transparently passed to the time selector, see [TimePicker·API Reference](/en-US/input/timepicker#API%20Reference)                                    |                                                                                                                                                                                                           | object                                                                                | **1.1.0**                 |
+| topSlot            | Render the top extra area                                                                                 | ReactNode                                                                                                                                                                                                 |                                                | **1.22.0**                   |
+| triggerRender      | Custom trigger rendering method                                                                                                                                                           | ({ placeholder: string }) => ReactNode                                                                                                                                                                    |                                                                                       | **0.34.0**                |
+| type               | Type, optional value: "date", "dateRange", "dateTime", "dateTimeRange", "month"                                                                                                           | string                                                                                                                                                                                                    | 'date'                                                                                | (type "month") **0.21.0** |
+| value              | Controlled value                                                                                                                                                                          | string\| Date\|number\| string[]\|Date[]\|number[]                                                                                                                                                        |                                                                                       |                           |
+| weekStartsOn       | Take the day of the week as the first day of the week, 0 for Sunday, 1 for Monday, and so on.                                                                                             | number                                                                                                                                                                                                    | 0                                                                                     |                           |
+| onBlur             | Callback when focus is lost                                                                                                                                                               | (e: domEvent) => void                                                                                                                                                                                     | () => {}                                                                              | **1.0.0**                 |
+| onCancel           | Cancel the callback when selected, enter the reference as the value of the last confirmed selection, only `type` equals "dateTime"or "dateTimeRange" and `needConfirm` equals true        | (date: Date\|Date[], dateStr: string\|string[]) => void) <br/>Before 1.0.0, it was (dateStr: string\|string [], date: Date\|Date[]) => void                                                               |                                                                                       | **0.18.0**                |
+| onChange           | A callback when the value changes                                                                                                                                                         | (date: Date\|Date[], dateStr: string\|string[]) => void) <br/>Before 1.0.0, it was (dateStr: string\|string [], date: Date\|Date[]) => void                                                               |                                                                                       |                           |
+| onClear            | A callback when click the clear button                                                                                                                                                    | (e: domEvent) => void                                                                                                                                                                                     | () => {}                                                                              | **1.16.0**           |
+| onConfirm          | Confirm the callback at the time of selection, enter the reference as the value of the current selection, only `type` equals "dateTime" or "dateTimeRange" and `needConfirm` equals true  | (date: Date\|Date[], dateStr: string\|string[]) => void) <br/>Before 1.0.0, it was (dateStr: string\|string [], date: Date\|Date[]) => void                                                               |                                                                                       | **0.18.0**                |
+| onFocus            | Callback when focus is obtained                                                                                                                                                           | (e: domEvent) => void                                                                                                                                                                                     | () => {}                                                                              | **1.0.0**                 |
+| onOpenChange       | Panel displays or hides callbacks to state switches                                                                                                                                       | (status: boolean) => void                                                                                                                                                                                 |                                                                                       |                           |
+| onPanelChange      | Callback when the year or date of the panel is switched|(date: DateType\|DateType[], dateStr: StringType\|StringType[])=>void|true|**1.28.0**|
+| onPresetClick      | Callback when click preset button                                                                          | (item: Object, e: Event) => void                                                                                                                                                                                 | () => {}                                               |   **1.24.0**                           |
+
+## Date and Time Format
+
+Adopted in the semi-ui component library [date-fns(v2.9.0)](https://date-fns.org/v2.9.0/docs/Getting-Started) As a date and time engine, formatting token means the following:
+
+-   `"y"`: Year
+-   `"M"`: month
+-   `"d"`: day
+-   `"H"`: hours
+-   `"h"`: hours (12h)
+-   `"m"`: minutes
+-   `"s"`: seconds
+
+The default date time is formatted to:
+
+-   `"date"`(date): `"yyyy-mm-dd`
+-   `"dateTime"`(date and time)`"yyyy-mm-dd HH:mm:ss"`
+-   `"month"`(month): `"yyyy-MM"`
+-   `"dateRange"`(Date Range): `"yyyy-mm-dd ~ yyyy-mm-dd"`
+-   `"dateTimeRange"`(Date and Time Range): `"yyyy-mm-dd HH:mm:ss ~ yyyy-mm-dd HH:mm:ss"`
+
+Multiple dates or times are used by default `","` (English comma) separated.
+
+> More token available [Date-fns official website](https://date-fns.org/v2.9.0/docs/Unicode-Tokens)
+
+## Design Tokens
+<DesignToken/>
+
+## FAQ
+
+-   **Date time picker, when you choose time, minute and second, you don't want to scroll infinitely. How to achieve the effect?**  
+    This behavior can be controlled by a specific switch in timePickerOpts, timePickerOpts={{scrollitemprops: {cycled: false}}}, and cycled is set to false
+
+-   **How to set the default display time when the panel is opened?**  
+    You can use the defaultPickerValue property.

+ 797 - 0
content/input/datepicker/index.md

@@ -0,0 +1,797 @@
+---
+localeCode: zh-CN
+order: 19
+category: 输入类
+title: DatePicker 日期选择器
+icon: doc-datepicker
+brief: 日期选择器用于帮助用户选择一个符合要求的、格式化的日期(时间)或日期(时间)范围
+---
+
+## 何时使用
+
+当用户需要输入一个日期,可以点击标准输入框,弹出日期面板进行选择。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { DatePicker } from '@douyinfe/semi-ui';
+```
+
+### 基本使用
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker onChange={(date, dateString) => console.log(dateString)} />;
+```
+
+### 小尺寸
+
+使用 density 可以控制日期面板的尺寸,`compact` 为小尺寸,`default` 为默认尺寸。v1.17.0 后支持。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return (
+        <div>
+            <DatePicker type="dateTime" density="compact" />
+            <br />
+            <br />
+            <DatePicker type="dateRange" density="compact" style={{ width: 260 }} />
+        </div>
+    );
+}
+```
+
+### 带内嵌标签
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <DatePicker insetLabel="结束日期" style={{ width: 240 }} />;
+}
+```
+
+### 多个日期选择
+
+将 `multiple` 设为 `true`,可以多选日期
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker multiple={true} style={{ width: 240 }} />;
+```
+
+### 日期与时间选择
+
+将 `type` 设定为 `dateTime`,可以选择日期时间。  
+同时,如果希望去掉 TimePicker 的无限循环滚动交互,可以通过 timePickerOpts 传入特定配置关闭。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <h4>默认日期与时间选择</h4>
+        <DatePicker type="dateTime" />
+        <br />
+        <br />
+        <h4>关闭时间列表无限循环</h4>
+        <DatePicker
+            type="dateTime"
+            timePickerOpts={{
+                scrollItemProps: { cycled: false },
+            }}
+        />
+    </>
+);
+```
+
+### 日期范围选择
+
+将 `type` 设定为 `dateRange`,可以选择日期范围
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker type="dateRange" style={{ width: 260 }} onChange={console.log} />;
+```
+
+<Notice type="primary" title="注意事项">
+    <div>type=dateRange 或 dateTimeRange 时,只有开始日期和结束日期都被选择后才会触发 onChange。</div>
+</Notice>
+
+### 日期范围时间选择
+
+将 `type` 设定为 `dateTimeRange`, 可以选择日期时间范围
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker type="dateTimeRange" style={{ width: 380 }} onChange={console.log} />;
+```
+
+### 同步切换双面板月份
+
+version: >= 1.28.0
+
+在范围选择的场景中, 开启 `syncSwitchMonth` 则允许双面板同步切换。默认为 false。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+    <DatePicker
+        // 双面板同步切换
+        syncSwitchMonth={true}
+        type="dateTimeRange"
+        style={{ width: 380 }}
+    />
+);
+```
+
+### 切换面板日期的回调
+
+版本:>=1.28.0
+
+`onPanelChange` 回调函数会在面板的月份或年份切换改变时被调用。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+    <DatePicker
+        syncSwitchMonth={true}
+        type="dateTimeRange"
+        style={{ width: 380 }}
+        onPanelChange={(date, dateString) => console.log(date, dateString)}
+    />
+);
+```
+
+### 周选择
+
+dateRange 搭配 startDateOffset 和 endDateOffset 可以进行单击范围选择,如周选择、双周选择。v1.10.0 后支持。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const handleChange = date => {
+        console.log('date changed', date);
+    };
+
+    return (
+        <div>
+            <h4>选择自然周</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                startDateOffset={date => dateFns.startOfWeek(date, { weekStartsOn: 1 })}
+                endDateOffset={date => dateFns.endOfWeek(date, { weekStartsOn: 1 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+            <h4>选择双周</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                startDateOffset={date => dateFns.startOfWeek(date, { weekStartsOn: 1 })}
+                endDateOffset={date => dateFns.add(dateFns.endOfWeek(date, { weekStartsOn: 1 }), { days: 7 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+            <h4>选择当前日和后6日</h4>
+            <DatePicker
+                style={{ width: 260 }}
+                type="dateRange"
+                weekStartsOn={1}
+                endDateOffset={date => dateFns.add(date, { days: 6 })}
+                onChange={handleChange}
+            />
+            <br />
+            <br />
+        </div>
+    );
+}
+```
+
+### 年月选择
+
+**版本:** >= 0.21.0
+
+将 `type` 设定为 `month`,可以进行年月选择。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker defaultValue={new Date()} type="month" style={{ width: 140 }} />;
+```
+
+### 确认日期时间选择
+
+**版本:** >= 0.18.0
+
+对于“日期时间”(type="dateTime")或“日期时间范围”(type="dateTimeRange")的选择,可以进行确认后才将值写入输入框内,你可以通过传递 needConfirm=true 来开启这种行为。
+
+同时支持 “确认”(onConfirm) 和 “取消”(onCancel) 两个按钮的点击回调。
+
+下面这个例子绑定了 onChange、onConfirm、onCancel 三种回调,你可以打开控制台查看打印信息的区别。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+    <DatePicker
+        type="dateTime"
+        needConfirm={true}
+        onConfirm={(...args) => {
+            console.log('Confirmed: ', ...args);
+        }}
+        onCancel={(...args) => {
+            console.log('Canceled: ', ...args);
+        }}
+        onChange={(...args) => {
+            console.log('Changed: ', ...args);
+        }}
+    />
+);
+```
+
+### 带有快捷方式的日期时间选择
+
+通过 `presets` 设定快捷日期选择
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => {
+    const presets = [
+        {
+            text: 'Today',
+            start: new Date(),
+            end: new Date(),
+        },
+        {
+            text: 'Tomorrow',
+            start: new Date(new Date().valueOf() + 1000 * 3600 * 24),
+            end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
+        },
+    ];
+    return <DatePicker type="dateTime" presets={presets} />;
+};
+```
+
+### 渲染顶部/底部额外区域
+
+通过 `topSlot` 和 `bottomSlot` 可以自定义渲染顶部和底部额外区域。
+
+```jsx live=true
+import React, { useState, useMemo } from 'react';
+import { DatePicker, Typography, Tabs, TabPane, Space } from '@douyinfe/semi-ui';
+import { IconBulb } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const { Text } = Typography;
+    const [activeTab, setActiveTab] = useState('1');
+    const [date, setDate] = useState();
+    const uedDisabledDate = currentDate => currentDate && currentDate.getDate() > 10 && currentDate.getDate() < 15;
+    const testDisabledDate = currentDate => currentDate && currentDate.getDate() > 15 && currentDate.getDate() < 25;
+
+    const handleTabChange = tab => {
+        setActiveTab(tab);
+        setDate();
+    };
+
+    const handleDateChange = value => {
+        setDate(value);
+    };
+
+    const disabledDate = useMemo(() => (activeTab === '1' ? uedDisabledDate : testDisabledDate), [activeTab]);
+
+    const TopSlot = function(props) {
+        const { style } = props;
+        return (
+            <Tabs
+                size="small"
+                onChange={handleTabChange}
+                activeKey={activeTab}
+                style={{ padding: '12px 20px 0', ...style }}
+            >
+                <TabPane tab="UED 排期" itemKey="1" />
+                <TabPane tab="测试排期" itemKey="2" />
+            </Tabs>
+        );
+    };
+
+    const BottomSlot = function(props) {
+        const { style } = props;
+        return (
+            <Space style={{ padding: '12px 20px', ...style }}>
+                <IconBulb style={{ color: 'rgba(var(--semi-amber-5), 1)' }} />
+                <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
+                    定版前请阅读
+                </Text>
+                <Text link={{ href: 'https://semi.design/', target: '_blank' }}>发版须知</Text>
+            </Space>
+        );
+    };
+
+    const MonthBottomSlot = function(props) {
+        const { style } = props;
+        return (
+            <Space style={{ padding: '12px 20px', ...style }}>
+                <IconBulb style={{ color: 'rgba(var(--semi-amber-5), 1)' }} />
+                <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
+                    请阅读
+                </Text>
+                <Text link={{ href: 'https://semi.design/', target: '_blank' }}>须知</Text>
+            </Space>
+        );
+    };
+
+    return (
+        <div>
+            <DatePicker
+                topSlot={<TopSlot />}
+                disabledDate={disabledDate}
+                value={date}
+                onChange={handleDateChange}
+                dropdownClassName="components-datepicker-demo-slot"
+                placeholder="请选择排期"
+            />
+            <br />
+            <br />
+            <DatePicker bottomSlot={<BottomSlot />} placeholder="请选择发版时间" />
+            <br />
+            <br />
+            <DatePicker type="month" bottomSlot={<MonthBottomSlot />} placeholder="请选择年月" />
+            <br />
+            <br />
+            <DatePicker
+                topSlot={<TopSlot style={{ padding: '8px 12px 0' }} />}
+                bottomSlot={<BottomSlot style={{ padding: '8px 12px' }} />}
+                density="compact"
+                placeholder="小尺寸"
+                dropdownClassName="components-datepicker-demo-slot"
+            />
+            <br />
+            <br />
+            <DatePicker type="dateTimeRange" bottomSlot={<BottomSlot />} style={{ width: 380 }} />
+            <br />
+            <br />
+        </div>
+    );
+}
+```
+
+```css
+.components-datepicker-demo-slot {
+    .semi-tabs-content {
+        padding: 0;
+    }
+
+    .semi-tabs-bar-line.semi-tabs-bar-top {
+        border-bottom: none;
+    }
+}
+```
+
+### 禁用日期选择
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker disabled type="dateTime" defaultValue={new Date()} />;
+```
+
+### 禁用部分日期或时间
+
+传入 `disabledDate` 可以禁用指定日期,传入 `disabledTime` 可以禁用指定时间,配合 `defaultPickerValue` 可以指定面板打开时所处的年月。
+
+`disabledDate` 和 `disabledTime`,接受的入参都为当前日期,前者返回一个 `boolean` 值,后者返回一个[对象](/zh-CN/input/timepicker#API_参考),将会透传给 `TimePicker` 组件。
+
+<Notice type="primary" title="注意事项">
+    <div>当你使用 timeZone 时,第一个参数为你选择的时区下时间(与onChange的第一个返回值类似)</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import * as dateFns from 'date-fns';
+import { range } from 'lodash-es';
+
+class App extends React.Component {
+    constructor(props = {}) {
+        super(props);
+
+        this.today = () => new Date();
+
+        this.nextValidMonth = () => {
+            const nextValidDate = this.today();
+            nextValidDate.setMonth((nextValidDate.getMonth() + 1) % 12);
+            return nextValidDate;
+        };
+
+        this.disabledTime = date =>
+            dateFns.isToday(date)
+                ? {
+                      disabledHours: () => [17, 18],
+                      disabledMinutes: hour => (19 === hour ? range(0, 10, 1) : []),
+                      disabledSeconds: (hour, minute) => (hour === 20 && minute === 20 ? range(0, 20, 1) : []),
+                  }
+                : null;
+
+        this.disabledTime2 = (date, panelType) => {
+            if (panelType === 'left') {
+                return { disabledHours: () => [17, 18] };
+            } else {
+                return { disabledHours: () => [12, 13, 14, 15, 16, 17, 18] };
+            }
+        };
+
+        this.disabledDate = date => {
+            const deadDate = this.today();
+            const month = deadDate.getMonth();
+            deadDate.setDate(28);
+            deadDate.setMonth((month + 1) % 12);
+            return date.getTime() < deadDate.getTime();
+        };
+    }
+
+    render() {
+        return (
+            <div>
+                <div>
+                    <h4>禁用时间:禁用今天下午5-6点</h4>
+                    <DatePicker type="dateTime" hideDisabledOptions={false} disabledTime={this.disabledTime} />
+                </div>
+                <div>
+                    <h4>禁用时间:两个面板禁用不同时间</h4>
+                    <DatePicker
+                        type="dateTimeRange"
+                        hideDisabledOptions={false}
+                        disabledTime={this.disabledTime2}
+                        style={{ width: 380 }}
+                    />
+                </div>
+                <div>
+                    <h4>禁用日期:禁用下个月28号之前的所有日期</h4>
+                    <DatePicker
+                        type="dateTimeRange"
+                        disabledDate={this.disabledDate}
+                        defaultPickerValue={this.nextValidMonth()}
+                        style={{ width: 380 }}
+                    />
+                </div>
+            </div>
+        );
+    }
+}
+```
+
+在 type 包含 range 时,可以根据当前选择动态禁止日期。options 参数 1.9.0 后支持。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import * as dateFns from 'date-fns';
+
+() => (
+    <div>
+        <h4>动态禁用日期:禁止选择之前的日期</h4>
+        <DatePicker
+            type={'dateRange'}
+            disabledDate={(date, options) => {
+                const { rangeStart } = options;
+                const startDate = dateFns.parseISO(rangeStart);
+                return dateFns.isBefore(date, startDate);
+            }}
+            style={{ width: 260 }}
+        />
+    </div>
+);
+```
+
+### 自定义显示格式
+
+可以通过 `format` 自定义显示格式
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+
+() => <DatePicker format="yyyy年MM月dd日 HH:mm" type="dateTime" defaultValue={new Date()} />;
+```
+
+### 自定义触发器
+
+**版本:**>=0.34.0
+
+默认情况下我们使用 `Input` 组件作为 `DatePicker` 组件的触发器,通过传递 `triggerRender` 方法你可以自定义这个触发器。
+
+```jsx live=true hideInDSM
+import React, { useState, useCallback, useMemo } from 'react';
+import * as dateFns from 'date-fns';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+import { DatePicker, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [date, setDate] = useState(new Date());
+    const formatToken = 'yyyy-MM-dd';
+    const onChange = useCallback(date => {
+        setDate(date);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setDate(null);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return date ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [date]);
+
+    return (
+        <DatePicker
+            onChange={onChange}
+            value={date}
+            format={formatToken}
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                    {(date && dateFns.format(date, formatToken)) || placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+### 自定义日期显示内容
+
+**版本:**>=1.4.0
+
+`renderDate: (dayNumber: number, fullDate: string) => ReactNode`,自定义日期内容。
+
+-   `dayNumber`:当前日。如 `13`。
+-   `fullDate`:当前日的完整日期。如 `2020-08-13`。
+
+```jsx live=true
+import React from 'react';
+import { DatePicker, Tooltip } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const dateStyle = {
+        width: '100%',
+        height: '100%',
+        border: '1px solid var(--semi-color-primary)',
+        display: 'flex',
+        justifyContent: 'center',
+        alignItems: 'center',
+    };
+    const renderDate = (dayNumber, fullDate) => {
+        if (dayNumber === 1) {
+            return (
+                <Tooltip content={'Always Day 1'}>
+                    <div style={dateStyle}>{dayNumber}</div>
+                </Tooltip>
+            );
+        }
+        return dayNumber;
+    };
+    return <DatePicker renderDate={renderDate} />;
+}
+```
+
+### 自定义日期格子渲染
+
+**版本:**>=1.4.0
+
+`renderFullDate: (dayNumber: number, fullDate: string, dayStatus: object) => ReactNode`, 自定义日期格子的渲染内容。
+
+`dayStatus` 表示当前格子的状态,包括的 `key` 有:
+
+```tsx
+type DayStatusType = {
+    isToday?: boolean; // 当前日
+    isSelected?: boolean; // 被选中
+    isDisabled?: boolean; // 被禁用
+    isSelectedStart?: boolean; // 选中开始
+    isSelectedEnd?: boolean; // 选中结束
+    isInRange?: boolean; // 范围选中日期内
+    isHover?: boolean; // 日期在选择项和hover日期之间
+    isOffsetRangeStart?: boolean; // 周选择开始
+    isOffsetRangeEnd?: boolean; // 周选择结束
+    isHoverInOffsetRange?: boolean; // hover在周选择内
+};
+```
+
+```jsx live=true
+import React from 'react';
+import { DatePicker } from '@douyinfe/semi-ui';
+import classNames from 'classnames';
+
+function Demo() {
+    const renderFullDate = (dayNumber, fullDate, dayStatus) => {
+        const { isInRange, isHover, isSelected, isSelectedStart, isSelectedEnd } = dayStatus;
+        const prefix = 'components-datepicker-demo';
+        const dateCls = classNames({
+            [`${prefix}-day-inrange`]: isInRange,
+            [`${prefix}-day-hover`]: isHover,
+            [`${prefix}-day-selected`]: isSelected,
+            [`${prefix}-day-selected-start`]: isSelectedStart,
+            [`${prefix}-day-selected-end`]: isSelectedEnd,
+        });
+        const dayStyle = {
+            display: 'flex',
+            alignItems: 'center',
+            justifyContent: 'center',
+            width: '80%',
+            height: '80%',
+            borderRadius: '50%',
+        };
+
+        return (
+            <div style={dayStyle} className={dateCls}>
+                {dayNumber}
+            </div>
+        );
+    };
+
+    return <DatePicker style={{ width: 260 }} type={'dateRange'} renderFullDate={renderFullDate} />;
+}
+```
+
+```css
+.components-datepicker-demo-day-inrange,
+.components-datepicker-demo-day-hover {
+    background: var(--semi-color-primary-light-hover);
+}
+
+.components-datepicker-demo-day-selected,
+.components-datepicker-demo-day-selected-start,
+.components-datepicker-demo-day-selected-end {
+    color: var(--semi-color-bg-2);
+    background: var(--semi-color-primary);
+}
+```
+
+## API 参考
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| autoAdjustOverflow | 浮层被遮挡时是否自动调整方向 | boolean | true | **0.34.0** |
+| autoFocus | 自动获取焦点 | boolean | false | **1.10.0** |
+| autoSwitchDate | 传入 false 时,通过面板上方左右按钮、下拉菜单更改年月时,不会自动切换日期 | boolean | true | **1.13.0** |
+| bottomSlot | 渲染底部额外区域 | ReactNode |  | **1.22.0** |
+| className | 类名 | string | - |  |
+| defaultOpen | 面板默认显示或隐藏 | boolean | false |  |
+| defaultPickerValue | 默认面板日期 | ValueType |  |  |
+| defaultValue | 默认值 | ValueType |  |  |
+| density | 面板的尺寸,可选值:`default`, `compact` | string | default | **1.17.0** |
+| disabled | 是否禁用 | boolean | false |  |
+| disabledDate | 日期禁止判断方法,返回为 true 时禁止该日期,options 参数 1.9.0 后支持,rangeEnd 1.29 后支持 | (date: Date, options: { rangeStart: string, rangeEnd: string }) => boolean | () => false |  |
+| disabledTime | 时间禁止配置,返回值将会作为参数透传给 [`TimePicker`](/zh-CN/input/timepicker#API_参考) | (date: Date \| Date[], panelType?: string) => ({ <br/>disabledHours:() => number[], <br/>disabledMinutes: (hour: number) => number[], <br/>disabledSeconds: (hour: number, minute: number) => number[] }) | () => false | **0.36.0** |
+| disabledTimePicker | 是否禁止时间选择 | boolean |  | **0.32.0** |
+| dropdownClassName | 下拉列表的 css 类名 | string |  | **1.13.0** |
+| dropdownStyle | 下拉列表的内联样式 | object |  | **1.13.0** |
+| endDateOffset | type 为 dateRange 时,设置单击选择范围的结束日期 | (selectedDate?: Date) => Date; | - | **1.10.0** |
+| format | 在输入框内展现的日期串格式 | string | 与 type 对应:详见[日期时间格式](#日期时间格式) |  |
+| getPopupContainer | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative` | function():HTMLElement | () => document.body |  |
+| hideDisabledOptions | 隐藏禁止选择的时间 | boolean | false |  |
+| inputReadOnly | 文本框是否 readonly | boolean | false |  |
+| inputStyle | 输入框样式 | object |  |  |
+| insetLabel | 前缀标签,优先级低于 `prefix` | string\|ReactNode |  |  |
+| max | multiple 为 true 时,多选的数目,不传或者值为 null\|undefined 的话无限制 | number | - |  |
+| motion | 是否开启面板展开的动画 | boolean | true |  |
+| multiple | 是否可以选择多个,仅支持 type="date" | boolean | false |  |
+| needConfirm | 是否需要“确认选择”,仅 type="dateTime"\|"dateTimeRange" 时有效 | boolean |  | **0.18.0** |
+| open | 面板显示或隐藏的受控属性 | boolean |  |  |
+| placeholder | 输入框提示文字 | string | 'Select date' |  |
+| position | 浮层位置,可选值同[Popover#API 参考·position 参数](/zh-CN/show/popover#API参考) | string | 'bottomLeft' |  |
+| prefix | 前缀内容 | string\|ReactNode |  |  |
+| presets | 日期时间快捷方式 | Array<{start:BaseValueType, end:BaseValueType, text:string}\| function():{start:BaseValueType, end:BaseValueType, text:string}> | [] |  |
+| rangeSeparator | 自定义范围类型输入框的日期分隔符 | string | '~' | **1.31.0** |
+| renderDate | 自定义日期显示内容 | (dayNumber, fullDate) => ReactNode | - | **1.4.0** |
+| renderFullDate | 自定义显示日期格子内容 | (dayNumber, fullDate, dayStatus) => ReactNode | - | **1.4.0** |
+| showClear | 是否显示清除按钮 | boolean | true | **0.35.0** |
+| size | 尺寸,可选值:"small", "default", "large" | string | 'default' |  |
+| spacing | 浮层与 trigger 的距离 | number | 4 | **1.9.0** |
+| startDateOffset | type 为 dateRange 时,设置单击选择范围的开始日期 | (selectedDate?: Date) => Date; | - | **1.10.0** |
+| stopPropagation | 是否阻止弹出层上的点击事件冒泡 | boolean | false |  |
+| style | 自定义样式 | CSSProperties |  |  |
+| syncSwitchMonth | 在范围选择的场景中,支持同步切换双面板的月份 | boolean | false | **1.28.0** |
+| timePickerOpts | 其他可以透传给时间选择器的参数,详见 [TimePicker·API 参考](/zh-CN/input/timepicker#API_参考) |  | object | **1.1.0** |
+| topSlot | 渲染顶部额外区域 | ReactNode |  | **1.22.0** |
+| triggerRender | 自定义触发器渲染方法,第一个参数是个 Object,详情看下方类型定义 | (props: TriggerRenderProps) => ReactNode | - | **0.34.0** |
+| type | 类型,可选值:"date", "dateRange", "dateTime", "dateTimeRange", "month" | string | 'date' | type="month" 需要 **0.21.0** |
+| validateStatus | 校验状态,可选值 default、error、warning,默认 default。仅影响展示样式 | string |  |  |
+| value | 受控的值 | ValueType |  |  |
+| weekStartsOn | 以周几作为每周第一天,0 代表周日,1 代表周一,以此类推 | number | 0 |  |
+| zIndex | 弹出面板的 zIndex | number | 1030 |  |
+| onBlur | 失去焦点时的回调 | (e: domEvent) => void | () => {} | **1.0.0** |
+| onCancel | 取消选择时的回调,入参为上次确认选择的值,仅 type="dateTime"\|"dateTimeRange" 且 needConfirm=true 时有效。 <br/>1.0.0 版本之前为 (dateStr: StringType, date: DateType) => void | (date: DateType, dateStr: StringType) => void |  | **0.18.0** |
+| onChange | 值变化时的回调。 <br/>1.0.0 版本之前为 (dateStr: StringType, date: DateType) => void | (date: DateType, dateStr: StringType) => void |  |  |
+| onChangeWithDateFirst | 0.x 中 onChange(string, Date), 1.0 后(Date, string)。此开关设为 false 时,入参顺序将与 0.x 版本保持一致 | boolean | true | **1.0.0** |
+| onClear | 点击 clear 按钮时触发 | (e: domEvent) => void | () => {} | **1.16.0** |
+| onConfirm | 确认选择时的回调,入参为当前选择的值,仅 type="dateTime"\|"dateTimeRange" 且 needConfirm=true 时有效。 <br/>1.0.0 版本之前为 (dateStr: StringType, date: DateType) => void | ( date: DateType, dateStr: StringType) => void |  | **0.18.0** |
+| onFocus | 获得焦点时的回调 | (e: domEvent) => void | () => {} | **1.0.0** |
+| onOpenChange | 面板显示或隐藏状态切换的回调 | (status: boolean) => void |  |  |
+| onPanelChange | 切换面板的年份或者日期时的回调 | (date: DateType\|DateType[], dateStr: StringType\|StringType[])=>void | function | **1.28.0** |
+| onPresetClick | 点击快捷选择按钮的回调 | (item: Object, e: Event) => void | () => {} | **1.24.0** |
+
+## 类型定义
+
+```typescript
+type BaseValueType = string | number | Date;
+type ValueType = BaseValueType | BaseValueType[];
+type DateType = Date | Date[];
+type StringType = string | string[];
+type TriggerRenderProps = {
+    value?: ValueType;
+    inputValue?: string;
+    placeholder?: string | string[];
+    autoFocus?: boolean;
+    size?: InputSize;
+    disabled?: boolean;
+    inputReadOnly?: boolean;
+    componentProps?: DatePickerProps;
+    [x: string]: any;
+};
+```
+
+## 设计变量
+
+<DesignToken/>
+
+## 日期时间格式
+
+semi-ui 组件库中采用 [date-fns(v2.9.0)](https://date-fns.org/v2.9.0/docs/Getting-Started) 作为日期时间引擎,格式化 token 含义如下:
+
+-   `"y"` :年
+-   `"M"` :月
+-   `"d"` :日
+-   `"H"` :小时
+-   `"m"` :分钟
+-   `"s"` :秒
+
+默认的日期时间会格式化为:
+
+-   `"date"`(日期):`"yyyy-MM-dd"`
+-   `"dateTime"`(日期时间):`"yyyy-MM-dd HH:mm:ss"`
+-   `"month"`(年月):`"yyyy-MM"`
+-   `"dateRange"`(日期范围):`"yyyy-MM-dd ~ yyyy-MM-dd"`
+-   `"dateTimeRange"`(日期时间范围):`"yyyy-MM-dd HH:mm:ss ~ yyyy-MM-dd HH:mm:ss"`
+
+多个日期或时间默认使用 `","` (英文逗号)分隔。
+
+> 更多 token 可以查阅 [date-fns 官网](https://date-fns.org/v2.9.0/docs/Unicode-Tokens)
+
+## FAQ
+
+-   **日期时间选择器,时分秒选择时不想要无限滚动效果如何实现?**  
+     可以通过 timePickerOpts 中的特定开关控制该行为, timePickerOpts={{ scrollItemProps: { cycled: false } }} ,cycled 设为 false 即可
+
+-   **如何设置面板打开时默认显示的时间?**  
+     可通过 defaultPickerValue 属性。

+ 1824 - 0
content/input/form/index-en-US.md

@@ -0,0 +1,1824 @@
+---
+localeCode: en-US
+order: 20
+category: Input
+title:  Form
+subTitle: Form
+icon: doc-form
+dir: column
+---
+
+
+## Form
+
+-   **Rerender on demand**, avoids unnecessary full-volume rendering, higher performance
+-   Easy to use, **simple structure**, avoids unnecessary hierarchical nesting
+-   FormState / FieldState can also be easily obtained from outside the Form
+    Provides an external method to operate inside the form: formApi / fieldApi
+-   Support for encapsulating custom components into form controls, and you can quickly access your team's components through the extension mechanism provided by Form (through `withField` HOC)
+-   Support Form level / Field level assignment, verification (synchronous / asynchronous)
+
+## Field
+
+Semi encapsulates all form controls (Input、Select、Checkbox、DatePicker etc.) with withField once.
+Taking over their data flow (value & onChange)  
+When in use, you need to import from the Form (note: only the control imported from the Form has data synchronization)
+
+### Supported Field Component
+
+-   `Input`, `InputNumber`, `TextArea`, `Select`, `Checkbox`, `Radio`, `RadioGroup`, `Switch`, `DatePicker`, `TimePicker`, `Slider`, `InputGroup`, `TreeSelect`, `Cascader`, `Rating`, `AutoComplete`, `Label`, `ErrorMessage`, `Section`、`TagInput`
+    All mounted under Form and declared directly in \<Form.Input\> and \<Form.Select\> when used.
+-   `Upload` is already planned and will be supported in the follow-up
+
+```javascript
+import { Form } from '@douyinfe/semi-ui';
+
+const FormInput = Form.Input;
+const FormSelect = Form.Select;
+const Option = FormSelect.Option;
+```
+
+The Field level component provided by Form, its `value` (or other properties specified by `valueKey`), onChange (or other callback functions specified by `onKeyChangeFnName`)
+Properties are hijacked by Form, so
+
+1. ** You don't need and shouldn't use `onChange` to sync, of course you can continue to listen to onChange events for the latest values **
+2. ** You cannot set the `value` of field with attributes such as `value`, `defaultValue`, `checked`, `defaultChecked`, etc. The default value can be set by Field's `initValue` or Form's `unitValues` **
+3. ** You should not modify the value of Form State directly, all changes to the data in the Form should be done by providing `formApi`, `fieldApi` **
+
+## Demos
+
+### Various ways to declare form
+
+Semi Form supports multiple writing at the same time.
+
+#### Basic Usage
+
+Add `field` property to each field component.
+You can also set label` properties for each field, by default is the same as field
+
+> Note: The field attribute is required props
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form layout='horizontal'>
+        <Form.Select field="role" label='UserRole' style={{width:120}}>
+            <Form.Select.Option value="admin">Admin</Form.Select.Option>
+            <Form.Select.Option value="user">User</Form.Select.Option>
+            <Form.Select.Option value="guest">Guest</Form.Select.Option>
+        </Form.Select>
+        <Form.Input field='userName' label='UserName' />
+        <Form.Input field='password' label='Password' />
+    </Form>
+)
+```
+
+#### Other forms of support
+
+When you need to get formState, formApi, values, etc. directly inside the Form structure, you can also use the following writing
+
+#### Via render props
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form render={({ formState, formApi, values }) => (
+        <>
+            <Form.Select field="role" label='Role' style={{width:120}}>
+                <Form.Select.Option value="admin">Admin</Form.Select.Option>
+                <Form.Select.Option value="user">User</Form.Select.Option>
+                <Form.Select.Option value="guest">Guest</Form.Select.Option>
+            </Form.Select>
+            <Form.Input field='userName' label='UserName' />
+            <Form.Input field='password' label='Password' />
+            <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+        </>
+    )} layout='horizontal'>
+    </Form>
+)
+```
+
+#### Via children function
+
+Children is a function that returns all form controls
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form layout='horizontal'>
+        {
+            ({ formState, values, formApi }) => (
+                <>
+                    <Form.Select field="role" label='Role' style={{width:120}}>
+                        <Form.Select.Option value="admin">Admin</Form.Select.Option>
+                        <Form.Select.Option value="user">User</Form.Select.Option>
+                        <Form.Select.Option value="guest">Guest</Form.Select.Option>
+                    </Form.Select>
+                    <Form.Input field='userName' label='UserName' />
+                    <Form.Input field='password' label='Password' />
+                    <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+                </>
+            )
+        }
+    </Form>
+)
+```
+
+#### Via props.component
+
+Pass the entire internal structure directly in the form through `component` attribute.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+  constructor() { super(); }
+  render() {
+      const fields = ({ formState, formApi, values }) => (
+          <>
+              <Form.Input field='Role'/>
+              <Form.Input field='UserName' />
+              <Form.Input field='Password' />
+              <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+          </>
+      );
+      return <Form component={fields} layout='horizontal'/>
+  }
+}
+```
+
+### Supported Fields example collection
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Col, Row, Button } from '@douyinfe/semi-ui';
+
+class BasicDemoWithInit extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            initValues: {
+                name: 'semi',
+                business: ['hotsoon'],
+                role: 'ued',
+                switch: true,
+            }
+        };
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi }
+
+    render() {
+        const { Input, InputNumber, AutoComplete, Select, TreeSelect, Cascader, DatePicker, TimePicker, TextArea, CheckboxGroup, Checkbox, RadioGroup, Radio, Slider, Rating, Switch, TagInput } = Form;
+        const { initValues } = this.state;
+        const plainOptions = ['A', 'B', 'C'];
+        const style = { width: '90%' };
+        const treeData = [
+            {
+                label: 'Asia',
+                value: 'Asia',
+                key: '0',
+                children: [
+                    {
+                        label: 'China',
+                        value: 'China',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: 'Beijing',
+                                value: 'Beijing',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: 'Shanghai',
+                                value: 'Shanghai',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: 'North America',
+                value: 'North America',
+                key: '1',
+            }
+        ];
+
+        return (
+            <Form
+                getFormApi={this.getFormApi}
+                initValues={initValues}
+                style={{ padding: 10, width: '100%' }}
+                onValueChange={(v)=>console.log(v)}
+            >
+                <Row>
+                    <Col span={12}>
+                        <Input
+                            field="name"
+                            label="Name(Input)"
+                            initValue={'mikeya'}
+                            style={style}
+                            trigger='blur'
+                        />
+                    </Col>
+                    <Col span={12}>
+                        <DatePicker field="date" label='Date(DatePicker)' style={style} placeholder='Choose data' />
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                        <Select field="role" style={style} label='Role(Select)' placeholder='Choose role'>
+                            <Select.Option value="qa">Quality Assurance</Select.Option>
+                            <Select.Option value="rd">Software Engineer</Select.Option>
+                            <Select.Option value="pm">Product Manager</Select.Option>
+                            <Select.Option value="ued">Designer</Select.Option>
+                        </Select>
+                    </Col>
+                    <Col span={12}>
+                        <Select
+                            field="business"
+                            multiple
+                            style={style}
+                            placeholder='Choose application'
+                            label="Application(Multiple Select)"
+                        >
+                            <Select.Option value="tiktok">Tiktok</Select.Option>
+                            <Select.Option value="hotsoon">Vigo</Select.Option>
+                            <Select.Option value="xigua">BuzzVideo</Select.Option>
+                        </Select>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                        <Form.Cascader
+                            placeholder="Choose Area"
+                            treeData={treeData}
+                            field='area'
+                            label='Area(Cascader)'
+                            style={style}
+                        >
+                        </Form.Cascader>
+                    </Col>
+                    <Col span={12}>
+                        <Form.TreeSelect
+                            field="tree"
+                            style={style}
+                            label='Node(TreeSelect)'
+                            placeholder='Select Service Node'
+                            treeData={treeData}
+                            filterTreeNode
+                        >
+                        </Form.TreeSelect>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                        <TextArea
+                            style={style}
+                            field='description'
+                            label='Apply Reason(TextArea)'
+                        />
+                    </Col>
+                    <Col span={12}>
+                        <CheckboxGroup
+                            field="type"
+                            label='Apply type(CheckboxGroup)'
+                            initValue={['user', 'admin']}
+                            rules={[
+                                { Requested: true }
+                            ]}
+                        >
+                            <Checkbox value="admin">admin</Checkbox>
+                            <Checkbox value="user">user</Checkbox>
+                            <Checkbox value="guest">guest</Checkbox>
+                            <Checkbox value="root">root</Checkbox>
+                        </CheckboxGroup>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                        <RadioGroup field="isMonopolize" label='Whether exclusive resources(Radio)'>
+                            <Radio value={true}>Yes</Radio>
+                            <Radio value={false}>No</Radio>
+                        </RadioGroup>
+                    </Col>
+                    <Col span={12}>
+                        <CheckboxGroup options={plainOptions} field="checkbox" label='Type(CheckboxGroup)' direction='horizontal'/>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                      <TimePicker field="time" label='End Time(TimePicker)' style={{ width: '90%' }}/>
+                    </Col>
+                    <Col span={12}>
+                        <InputNumber field='number' label='Number of applications(InputNumber)' initValue={20} style={style}/>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                      <Slider field="range" label='Resource usage alarm threshold(%)(Slider)' initValue={10} style={{ width: '90%' }}/>
+                    </Col>
+                    <Col span={12}>
+                      <Switch field='switch' label='Switch(Switch)'/>
+                    </Col>
+                </Row>
+                <Row>
+                    <Col span={12}>
+                      <Rating field="rating" label='Satisfaction(Rating)' initValue={2} style={{ width: '90%' }}/>
+                    </Col>
+                    <Col span={12}>
+                        <TagInput 
+                            field="product"
+                            label='Product(TagInput)'
+                            defaultValue={['tiktok','hotsoon']}
+                            style={style}
+                        />
+                    </Col>
+                </Row>
+                <Checkbox value="false" field="agree" noLabel={true}>
+                    I have read and understood the relevant regulations(Checkbox)
+                </Checkbox>
+                <Button type="primary" htmlType="submit" className="btn-margin-right">Submit</Button>
+                <Button htmlType="reset">Reset</Button>
+            </Form>
+        );
+    }
+}
+```
+
+### Field binding syntax
+
+Every Field must have a `field` property. This is how the form manages the state of this field.
+See the field syntax section below for additional details on what you can pass in for field.
+
+The field can be a simple string, can be contained`.`Or`[]`String that supports multi-level nesting  
+Below is an example of the field name and their mapping path in FormState
+
+| Field                  | Resolution                         |
+| ---------------------- | ---------------------------------- |
+| username               | formState.values.username          |
+| user\[0\]              | formState.values.user\[0\]         |
+| siblings.1             | formState.values.siblings\[1\]     |
+| siblings\['2'\]        | formState.values.siblings\[2\]     |
+| parents\[0\].name      | formState.values.parents\[0\].name |
+| parents\[1\]\['name'\] | formState.values.parents\[1\].name |
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Row, Col, Toast, TextArea } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        onSubmit={values => Toast.info({ content: JSON.stringify(values) })}
+    >
+        {
+            ({ formState, values, formApi }) => (
+                <Row>
+                    <Col span={12}>
+                        <Form.Input field='username' placeholder='Try input something'/>
+                        <Form.Input field='user[0]' placeholder='Try input something'/>
+                        <Form.Input field='siblings.1' placeholder='Try input something'/>
+                        <Form.Input field="siblings['2']" placeholder='Try input something'/>
+                        <Form.Input field='parents[0].name' placeholder='Try input something'/>
+                        <Form.Input field="parents[1]['name']" placeholder='Try input something'/>
+                    </Col>
+                    <Col span={10} offset={1} style={{marginTop: 12}}>
+                        <Form.Label text='formState.values in real time:'></Form.Label>
+                        <TextArea value={JSON.stringify(formState.values)}></TextArea>
+                    </Col>
+                </Row>
+            )
+        }
+    </Form>
+)
+```
+
+### Form layout
+
+-   Vertical Layout: Arrange each field vertically (By default)  
+     Semi Design recommends a vertical layout.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button, Toast } from '@douyinfe/semi-ui';
+
+() => {
+ const handleSubmit = (values) => {
+   console.log(values);
+   Toast.info('Submit Success');
+ }
+ return (
+     <Form onSubmit={values => handleSubmit(values)} style={{width: 400}}>
+        {({formState, values, formApi}) => (
+            <>
+                <Form.Input field='phone' label='PhoneNumber' style={{ width: '100%' }} placeholder='Enter your phone number'></Form.Input>
+                <Form.Input field='password' label='Password' style={{ width: '100%' }} placeholder='Enter your password'></Form.Input>
+                <Form.Checkbox field='agree' noLabel>I have read and agree to the terms of service</Form.Checkbox>
+                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
+                  <p>
+                      <span>Or</span><Button theme='borderless' style={{ color: 'rgb(101, 178, 252)', marginLeft: 10, cursor:'pointer' }}>Sign up</Button>
+                  </p>
+                  <Button disabled={!values.agree} htmlType='submit' type="tertiary">Log in</Button>
+                </div>
+            </>
+        )}
+    </Form>
+ )
+}
+```
+
+-   Horizontal Layout: Arrange each field horizontally
+    You can use the horizontal layout by setting `layout='layout'`
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form layout='horizontal'>
+        <Form.Input field='phone' label='PhoneNumber' placeholder='Enter your phone number'></Form.Input>
+        <Form.Input field='password' label='Password' placeholder='Enter your password'></Form.Input>
+    </Form>
+)
+```
+
+-   Label Position, Label Align  
+     You can control the position of the label in the Field and the direction of text alignment by setting `labelPosition`, `labelAlign`
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Select } from '@douyinfe/semi-ui';
+
+class BasicDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            labelPosition: 'left',
+            labelAlign: 'left',
+            labelWidth: '180px'
+        };
+        this.changeLabelPos = this.changeLabelPos.bind(this);
+        this.changeLabelAlign = this.changeLabelAlign.bind(this);
+    }
+
+
+    changeLabelPos(labelPosition) {
+        let labelWidth;
+        labelPosition === 'left' ? labelWidth = '180px' : labelWidth = 'auto';
+        this.setState({ labelPosition, labelWidth })
+    }
+
+    changeLabelAlign(labelAlign) { this.setState({ labelAlign }) }
+
+    render() {
+        const { labelPosition, labelAlign, labelWidth } = this.state;
+        return (
+            <>
+            <div style={{borderBottom: '1px solid var(--semi-color-text-3)', paddingBottom: 10 }}>
+                <Form.Label style={{ marginLeft: 10 }}>Switch Label Position:</Form.Label>
+                <Select onChange={this.changeLabelPos} value={labelPosition} style={{width: 100}}>
+                    <Select.Option value='top'>top</Select.Option>
+                    <Select.Option value='left'>left</Select.Option>
+                </Select>
+                <Form.Label style={{ marginLeft: 10 }}>Switch Label Text Align</Form.Label>
+                <Select onChange={this.changeLabelAlign} value={labelAlign} style={{width: 100}}>
+                    <Select.Option value='left'>left</Select.Option>
+                    <Select.Option value='right'>right</Select.Option>
+                </Select>
+            </div>
+            <Form
+                labelPosition={labelPosition}
+                labelWidth={labelWidth}
+                labelAlign={labelAlign}
+                style={{ padding: '10px', width: 600 }}>
+                    <Form.Input
+                        field="input"
+                        label="PhoneNumber"
+                        trigger='blur'
+                        style={{width: 200}}
+                        rules={[
+                            { required: true, message: 'required Error' },
+                            { type: 'string', message: 'type error' },
+                            { validator: (rule, value) => value === 'semi', message: 'not semi' }
+                        ]}
+                    />
+                    <Form.Switch label="Agree" field='agree'/>
+                    <Form.InputNumber field='price' label='price' style={{width: 200}}/>
+                    <Form.Select label="Name" field='name' style={{width: 200}}>
+                        <Option value="mike">mike</Option>
+                        <Option value="jane">jane</Option>
+                        <Option value="kate">kate</Option>
+                    </Form.Select>
+                    <Form.CheckboxGroup label="Role" field='role' direction='horizontal'>
+                        <Checkbox value="admin">admin</Checkbox>
+                        <Checkbox value="user">user</Checkbox>
+                        <Checkbox value="guest">guest</Checkbox>
+                        <Checkbox value="root">root</Checkbox>
+                    </Form.CheckboxGroup>
+                    <Form.RadioGroup field="Sex">
+                        <Radio value="1">man</Radio>
+                        <Radio value="2">woman</Radio>
+                    </Form.RadioGroup>
+            </Form>
+            </>
+        );
+    }
+}
+```
+
+-   A more complex layout.  
+    You can also combine the `Row` and `Col` provided by the `Grid` to arrange the form structure as you want.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Row, Col } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        labelPosition='top'
+        getFormApi={this.getFormApi}
+        style={{ padding: '10px' }}>
+        <Row>
+            <Col span={8}>
+                <Form.Input
+                    field="nickName1"
+                    label="NickName"
+                    style={{ width: '250px' }}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'semi', message: 'not semi' }
+                    ]}
+                />
+            </Col>
+            <Col span={8}>
+                <Form.DatePicker field='date1' label='Valid Date' style={{ width: '250px' }}/>
+            </Col>
+            <Col span={8}>
+                <Form.Select label="Application" field='business1' style={{ width: '250px' }}>
+                    <Form.Select.Option value="tiktok">Tiktok</Form.Select.Option>
+                    <Form.Select.Option value="hotsoon">Vigo</Form.Select.Option>
+                    <Form.Select.Option value="xigua">BussVideo</Form.Select.Option>
+                </Form.Select>
+            </Col>
+        </Row>
+        <Row>
+            <Col span={6}>
+                <Form.Input
+                    field="nickName2"
+                    label="NickName"
+                    style={{ width: '200px' }}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'semi', message: 'not semi' }
+                    ]}
+                />
+            </Col>
+            <Col span={6}>
+                <Form.DatePicker field='date2' label='Valid Date' style={{ width: '200px' }}/>
+            </Col>
+            <Col span={6}>
+                <Form.Select label="Application" field='business2' style={{ width: '250px' }}>
+                    <Form.Select.Option value="tiktok">Tiktok</Form.Select.Option>
+                    <Form.Select.Option value="hotsoon">Vigo</Form.Select.Option>
+                    <Form.Select.Option value="xigua">BussVideo</Form.Select.Option>
+                </Form.Select>
+            </Col>
+            <Col span={6}>
+                <Form.Select field="role" style={{ width: '250px' }} label='Role(Select)' placeholder='Choose role'>
+                    <Form.Select.Option value="qa">Quality Assurance</Form.Select.Option>
+                    <Form.Select.Option value="rd">Software Engineer</Form.Select.Option>
+                    <Form.Select.Option value="pm">Product Manager</Form.Select.Option>
+                    <Form.Select.Option value="ued">Designer</Form.Select.Option>
+                </Form.Select>
+            </Col>
+        </Row>
+    </Form>
+)
+```
+
+### wrapper Col / label Col
+
+When you need to set a uniform layout for all Fields in a Form, you can set `wrapperCol` and `labelCol` on the `Form` to quickly generate the layout. No need to manually use `Row`, `Col` manual layout.  
+`wrapperCol`,`labelCol`Property Configuration Reference [Col components](/en-US/basic/grid#Col)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        wrapperCol={{ span: 20 }}
+        labelCol={{ span: 2 }}
+        labelPosition='left'
+        labelAlign='right'
+    >
+        <Form.Input field='name' style={{width: 250}} label='Name' placeholder='Input Name' trigger='blur' />
+        <Form.Select field="role" label='Role' placeholder='Choose Role' style={{width: 250}}>
+            <Form.Select.Option value="qa">Quality Assurance</Form.Select.Option>
+            <Form.Select.Option value="rd">Software Engineer</Form.Select.Option>
+            <Form.Select.Option value="pm">Product Manager</Form.Select.Option>
+            <Form.Select.Option value="ued">Designer</Form.Select.Option>
+        </Form.Select>
+    </Form>
+)
+```
+
+### Remove automatically added Label
+
+Form will automatically inserts `Label` for Field Component. If you do not need to automatically insert the `Label` module, you can turn off this feature by setting `noLabel=true` in Field
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form onSubmit={(values) => console.log(values)} style={{ width: 400 }}>
+        <Form.Input field='name' label='UserName' trigger='blur' noLabel={true} style={{width: 250}} placeholder='Input userName'/>
+        <Form.Select field="role" label='UserRole' style={{ width: '250px' }} noLabel={true} placeholder='Choose role'>
+            <Form.Select.Option value="qa">Quality Assurance</Form.Select.Option>
+            <Form.Select.Option value="rd">Software Engineer</Form.Select.Option>
+            <Form.Select.Option value="pm">Product Manager</Form.Select.Option>
+            <Form.Select.Option value="ued">Designer</Form.Select.Option>
+        </Form.Select>
+    </Form>
+)
+```
+
+### Export Label, ErrorMessage use
+
+When the built-in Label and ErrorMessage layout does not meet the business requirements, you need to combine the positions yourself, but you want to use the default styles of Label and ErrorMessage directly.  
+you can import them from the `Form` module, and combine `Form.Label` / `Form.ErrorMessage` by yourself.  
+For details of their API, refer to [Label](#Form.Label) / [ErrorMessage](#Form.ErrorMessage)
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Label, ErrorMessage } = Form;
+```
+
+### Use Form.Slot
+
+When your custom component needs to maintain the same layout style as the Field component, you can place your custom component in `Form.Slot`  
+`labelWidth`, `labelAlign`, `wrapperCol`, `labelCol` set on the Form component automatically acts on `Form.Slot`  
+For the Slot property configuration, refer to [Form.Slot](#Form.Slot)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+class AssistComponent extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        return (
+            <Form
+                onChange={v=>console.log(v)}
+                onSubmit={v=>console.log(v)}
+                style={{width: 600}}
+                labelPosition='left'
+                labelWidth={100}
+            >
+                <Form.Input field='effectName' label='EffectName' style={{width: 250}}/>
+                <Form.Select
+                    style={{width: 300}}
+                    field="type"
+                    label="EffectType"
+                >
+                    <Form.Select.Option value="faceSticker">FaceSticker</Form.Select.Option>
+                    <Form.Select.Option value="backgroundSticker">BackgroundSticker</Form.Select.Option>
+                </Form.Select>
+                <Form.ErrorMessage />
+                <Form.Slot label={{ text: 'SlotA' }}>
+                    <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>
+                        I'm Semi Form SlotA, a custom ReactNode
+                    </div>
+                </Form.Slot>
+                <Form.Slot label={{ text: 'SlotB', width: 160, align: 'right' }}>
+                    <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>
+                        I'm Semi Form SlotA, i have different labelWidth and textAlign.
+                    </div>
+                </Form.Slot>
+            </Form>
+    )}
+}
+```
+
+### Embedded Label
+
+By setting the `labelPositon` to`inset`, you can embed label in the field component. This feature currently support `Input`, `InputNumber`, `DatePicker`, `TimePicker`, `Select`, `Cascader`, `TreeSelect`
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+() => (
+    <Form labelPosition='inset' layout='horizontal'>
+        <Form.Input field='name' label='UserName' trigger='blur' style={{width: 250}} placeholder='Input userName'/>
+        <Form.Select field="role" label='UserRole' style={{ width: '250px' }}>
+            <Form.Select.Option value="qa">Quality Assurance</Form.Select.Option>
+            <Form.Select.Option value="rd">Software Engineer</Form.Select.Option>
+            <Form.Select.Option value="pm">Product Manager</Form.Select.Option>
+            <Form.Select.Option value="ued">Designer</Form.Select.Option>
+        </Form.Select>
+        <Form.DatePicker field="date" label='Start Date' style={{ width: '250px' }}>
+        </Form.DatePicker>
+    </Form>
+)
+```
+
+### Using Input Group
+
+When you need to combine some fileds to use, you can use `Form.InputGroup` to wrap them.  
+In Semi Form, when you using field components like `Form.Input`、`Form.Select`, Form will insert Label module automatically for them.  
+But usually, in`InputGroup` you only need a Label belonging to the entire Group.
+You can set the label property in the `InputGroup` to insert a Label belonging to the Group  
+`label` configurable properties, see [Label](#Form.Label)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Form onSubmit={(values) => console.log(values)} labelPosition='top' style={{ width: 400 }}>
+        <Form.InputGroup label={{ text: (<span>PhoneNumber</span>), required: true }} labelPosition='top'>
+            <Form.Select style={{ width: 150 }} field='phonePrefix' initValue='+86' rules={[{ required: true }]} showClear>
+                <Form.Select.Option value='+1'>USA +1</Form.Select.Option>
+                <Form.Select.Option value='+86'>China +86</Form.Select.Option>
+                <Form.Select.Option value='+81'>Japan+81</Form.Select.Option>
+            </Form.Select>
+            <Form.Input initValue='18912345678' style={{ width: 250 }} field='phoneNumber' rules={[{ required: true }]} showClear/>
+        </Form.InputGroup>
+        <Form.Input field='name' trigger='blur' initValue='Semi' label='Name'></Form.Input>
+        <Button htmlType='submit'>Submit</Button>
+    </Form>
+)
+```
+
+### Form in the Modal pop-up layer
+
+You can place the Form in Modal and load it as a popup.  
+When submitting, use `formApi.validate()` to centrally verify the Field
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Modal, Button, Row, Col } from '@douyinfe/semi-ui';
+
+class ModalFormDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            visible: false,
+        }
+        this.showDialog = this.showDialog.bind(this);
+        this.handleOk = this.handleOk.bind(this);
+        this.handleCancel = this.handleCancel.bind(this);
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    showDialog() {
+        this.setState({ visible: true });
+    }
+
+    handleOk() {
+        this.formApi.validate()
+            .then((values) => {
+                console.log(values)
+            })
+            .catch((errors) => {
+                console.log(errors)
+            });
+    }
+
+    handleCancel() {
+        this.setState({ visible: false })
+    }
+
+    getFormApi(formApi) {
+        this.formApi = formApi;
+    }
+
+    render(){
+        const { visible } = this.state;
+        let message = 'Required';
+        return (
+            <>
+                <Button onClick={this.showDialog}>Open Dialog</Button>
+                <Modal
+                    title="New"
+                    visible={visible}
+                    onOk={this.handleOk}
+                    style={{width: 600}}
+                    onCancel={this.handleCancel}
+                >
+                    <Form
+                        getFormApi={this.getFormApi}
+                    >
+                        <Row>
+                            <Col span={7}>
+                                <Form.Select
+                                    field='region'
+                                    label="Country/Region"
+                                    style={{width:120}}
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                >
+                                    <Option value="China">China</Option>
+                                    <Option value="US">USA</Option>
+                                    <Option value="Europe">Europe</Option>
+                                    <Option value="Japan">Japan</Option>
+                                </Form.Select>
+                            </Col>
+                            <Col span={17}>
+                                <Form.Input
+                                    field='owner'
+                                    label="Owner"
+                                    trigger='blur'
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                />
+                            </Col>
+                            <Col span={7}>
+                                <Form.Select
+                                    field='area'
+                                    label="Area"
+                                    placeholder='Choose Area'
+                                    style={{width:120}}
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                >
+                                    <Form.Select.Option value="China">China</Form.Select.Option>
+                                    <Form.Select.Option value="US">USA</Form.Select.Option>
+                                    <Form.Select.Option value="Europe">Europe</Form.Select.Option>
+                                    <Form.Select.Option value="Japan">Japan</Form.Select.Option>
+                                </Form.Select>
+                            </Col>
+                            <Col span={17}>
+                                <Form.Input
+                                    field='department'
+                                    label="Department"
+                                    trigger='blur'
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                />
+                            </Col>
+                        </Row>
+                    </Form>
+                </Modal>
+            </>
+        );
+    }
+}
+```
+
+### Configure initial values and verification rules
+
+-   You can configure check rules for each Field through `rules`  
+     The verification library inside the Form is based on async-validator, and more configuration rules can be found in its [official documentation](https://github.com/yiminghe/async-validator)
+-   You can uniformly set the initial value for the entire form through the `initValues` of form, or you can set the initial value through `initValue` in each field (the latter has a higher priority)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+class BasicDemoWithInit extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            initValues: {
+                name: 'semi',
+                role: 'rd'
+            }
+        };
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi }
+
+    render() {
+        const { Select, Input } = Form;
+        const style = { width: '100%' }
+        return (
+            <Form initValues={this.state.initValues}>
+                <Input
+                    field="name"
+                    label="Name(Input)"
+                    style={style}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                    ]}
+                />
+                <Select field="role" style={style} label='Role' placeholder='Choose Role' initValue={'pm'}>
+                    <Select.Option value="qa">Quality Assurance</Select.Option>
+                    <Select.Option value="rd">Software Engineer</Select.Option>
+                    <Select.Option value="pm">Product Manager</Select.Option>
+                    <Select.Option value="ued">Designer</Select.Option>
+                </Select>
+            </Form>
+        )
+    }
+}
+```
+
+### Custom Validate (Form Level)
+
+You can set a custom validation function validateFields for the `form` as a whole, which will be called when submit
+
+#### Synchronous Validate
+
+When validate success, you should return an empty string.  
+When validate fails, you should return the error message (Object, key is fieldName, value is the corresponding error message)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FormLevelValidateSync extends React.Component {
+    constructor() {
+        super();
+        this.syncValidate = this.syncValidate.bind(this);
+    }
+
+    syncValidate(values) {
+        const errors = {};
+        if (values.name !== 'mike') {
+            errors.name = 'you must name mike';
+        }
+        if (values.sex !== 'female') {
+            errors.sex = 'must be woman';
+        }
+        errors.familyName = [
+            { before: 'before errror balabala ', after: 'after error balabala' },
+            'familyName[1] error balabala'
+        ];
+        return errors;
+    }
+
+    render() {
+        return (
+            <Form validateFields={this.syncValidate} layout='horizontal'>
+                <Form.Input field='name' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].before' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].after' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[1]' trigger='blur'></Form.Input>
+                <div style={{display: 'flex', alignItems: 'flex-end'}}>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </div>
+            </Form >
+        );
+    }
+}
+```
+
+#### Asynchronous Validate
+
+For asynchronous validation, you should return a promise. In promise.then() you need to return the corresponding error message.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FormLevelValidateAsync extends React.Component {
+    constructor() {
+        super();
+        this.asyncValidate = this.asyncValidate.bind(this);
+    }
+
+    asyncValidate(values) {
+        const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
+        return sleep(2000).then(() => {
+            let errors = {};
+            if (values.name !== 'mike') {
+                errors.name = 'you must name mike';
+            }
+            if (values.sex !== 'female') {
+                errors.sex = 'sex not valid';
+            }
+            return errors;
+        });
+    }
+
+    render() {
+        return (
+            <Form validateFields={this.asyncValidate} layout='horizontal'>
+                <Form.Input field='name' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].before' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[1]' trigger='blur'></Form.Input>
+                <Form.Input field='sex' trigger='blur'></Form.Input>
+                <div style={{display: 'flex', alignItems: 'flex-end'}}>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </div>
+            </Form >
+        );
+    }
+}
+```
+
+### Custom Validate (Field Level)
+
+You can specify a custom validation function for field. Supports synchronous and asynchronous validation (by returning promises)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FieldLevelValidateDemo extends React.Component {
+    constructor() {
+        super();
+        this.validateName = this.validateName.bind(this);
+        this.asyncValidate = this.asyncValidate.bind(this);
+    }
+
+    validateName(val) {
+        if (!val) {
+             return '【sync】can\'t be empty';
+        } else if (val.length <= 5) {
+            return '【sync】must more than 5';
+        }
+        return '';
+    }
+
+    asyncValidate(val, values) {
+        const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
+        return sleep(2000).then(() => {
+            if (!val) {
+                return '【async】can\'t be empty';
+            } else if (val.length <= 5) {
+                return '【async】must more than 5';
+            } else {
+                return '';
+            }
+        });
+    }
+
+    render() {
+        return (
+            <Form>
+                <Form.Input field='name' label='【name】asyncValidate after 2s' validate={this.asyncValidate} trigger='blur'></Form.Input>
+                <Form.Input field='familyName' label='【familyName】syncValidate' validate={this.validateName} trigger='blur'></Form.Input>
+                <Button htmlType="reset">reset</Button>
+            </Form >
+        );
+    }
+}
+```
+
+### Linkage Fields
+
+You can achieve the linkage between Fields by listening to the `onChange` of Field and then using formApi to make modifications.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button, Row } from '@douyinfe/semi-ui';
+
+class LinkFieldForm extends React.Component {
+    constructor() {
+        super();
+        this.getFormApi = this.getFormApi.bind(this);
+        this.handleSelectChange = this.handleSelectChange.bind(this);
+    }
+
+    handleSelectChange(value) {
+        let text = value === 'male' ? 'Hi male' : 'Hi female!';
+        this.formApi.setValue('Note', text);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi; }
+
+    render() {
+        return (
+            <Form getFormApi={this.getFormApi} onValueChange={values => console.log(values) } style={{ width: 300 }}>
+                <Form.Input field="Note" style={{ width: 300 }} placeholder='Automatically update after choose Sex'/>
+                <Form.Select field="Sex" onChange={this.handleSelectChange} style={{ width: 300 }}>
+                    <Form.Select.Option value="female">female</Form.Select.Option>
+                    <Form.Select.Option value="male">male</Form.Select.Option>
+                </Form.Select>
+                <Row>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </Row>
+            </Form>
+        );
+    }
+}
+```
+
+### Dynamic form
+
+#### Dynamically add and delete fields
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Form style={{ width: 450 }}>
+        {({ formState }) => (
+            <React.Fragment>
+                <Form.Input field="name" label='Name' />
+                <Form.RadioGroup field="isAnchor" label='Is registered anchor'>
+                    <Form.Radio value="yes">yes</Form.Radio>
+                    <Form.Radio value="no">no</Form.Radio>
+                </Form.RadioGroup>
+                {formState.values.isAnchor === 'yes' ? (
+                    <Form.Input field="liveRoom" label='Live room name' />
+                ) : null}
+                <Button htmlType="submit">Submit</Button>
+            </React.Fragment>
+        )}
+    </Form>
+)
+```
+
+#### Add or delete form items dynamically - by use ArrayField
+
+For array items that are dynamically added or deleted, we provide the `ArrayField` component to simplify the operation of add / remove
+
+```jsx live=true dir="column"
+import React from 'react';
+import { ArrayField, TextArea, Button, Form, useFormState } from '@douyinfe/semi-ui';
+
+class ArrayFieldDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            menu: [
+                { name: 'Face stickers', type: '2D' },
+                { name: 'Background sticker', type: '3D' },
+            ]
+        }
+    }
+
+    render() {
+        let { menu } = this.state;
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <TextArea style={{marginTop: 10}} value={JSON.stringify(formState)} />
+            );
+        };
+        return (
+            <Form style={{ width: 500 }} labelPosition='left' allowEmpty>
+                <ArrayField field='effects' initValue={menu}>
+                    {({ add, arrayFields }) => (
+                        <React.Fragment>
+                            <Button onClick={add}>Add</Button>
+                            {
+                                arrayFields.map(({ field, key, remove }, i) => (
+                                    <div key={key} style={{ width: 1000, display: 'flex' }}>
+                                        <Form.Input
+                                            field={`${field}[name]`}
+                                            label={`Effect Name:`}
+                                            style={{width: 200, marginRight: 16}}
+                                        >
+                                        </Form.Input>
+                                        <Form.Select
+                                            field={`${field}[type]`}
+                                            label={`Effect Type:`}
+                                            style={{width: 90}}
+                                        >
+                                            <Form.Select.Option value='2D'>2D</Form.Select.Option>
+                                            <Form.Select.Option value='3D'>3D</Form.Select.Option>
+                                        </Form.Select>
+                                        <Button type='danger' onClick={remove} style={{ margin: 16 }}>remove</Button>
+                                    </div>
+                                ))
+                            }
+                        </React.Fragment>
+                    )}
+                </ArrayField>
+                <ComponentUsingFormState />
+            </Form>
+        );
+    }
+}
+```
+
+#### Add or delete form items dynamically - by use formApi
+
+If you don't use ArrayField, you can use the provided formApi to manually add or delete formState.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button, TextArea } from '@douyinfe/semi-ui';
+
+class ArrayDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            initValues: {
+                effects: [
+                    { name: 'Face stickers', type: '2D', key: 1 },
+                    { name: 'Background sticker', type: '3D', key: 2 },
+                ]
+            }
+        };
+        this.id = 3;
+        this.getFormApi = this.getFormApi.bind(this);
+        this.add = this.add.bind(this);
+        this.remove = this.remove.bind(this);
+        this.renderItems = this.renderItems.bind(this);
+    }
+    getFormApi(formApi) {
+        this.formApi = formApi;
+    }
+    add(obj) {
+        let effects = this.formApi.getValue('effects');
+        if (!effects) {
+            effects = [];
+        }
+        effects.push({ name: '', type: '', key: this.id++  });
+        this.formApi.setValue('effects', effects);
+    }
+    remove(key) {
+        let effects = this.formApi.getValue('effects');
+        effects = effects.filter((effect, index) => key !== effect.key);
+        if (!effects.length) {
+            effects = undefined;
+        }
+        this.formApi.setValue('effects', effects);
+    }
+    renderItems(formState, values) {
+        return values.effects && values.effects.map((effect, i) => (
+            <div key={effect.key} style={{ width: 1000, display: 'flex' }}>
+                <Form.Input field={`effects[${i}].name`} style={{width: 200, marginRight: 16}}></Form.Input>
+                <Form.Select field={`effects[${i}].type`} style={{width: 90}}>
+                    <Form.Select.Option value='2D'>2D</Form.Select.Option>
+                    <Form.Select.Option value='3D'>3D</Form.Select.Option>
+                </Form.Select>
+                <Button type='danger' onClick={() => this.remove(effect.key)} style={{ margin: 16 }}>Remove</Button>
+            </div>
+        ))
+    }
+    render() {
+        let { initValues } = this.state;
+        return (
+            <Form
+                getFormApi={this.getFormApi}
+                initValues={initValues}
+                style={{ width: 500 }}
+                labelPosition='left'
+                labelWidth='180px'
+            >
+                {({ formState, values }) => (
+                    <>
+                        <Button onClick={this.add}>add</Button>
+                        {this.renderItems(formState, values)}
+                        <TextArea style={{marginTop: 10}} value={JSON.stringify(formState.values)} />
+                    </>
+                )}
+            </Form>
+        );
+    }
+}
+```
+
+### Use of Hook
+
+We provide four Hooks so that you can easily access Form internal state and call Form and Field related api in Functional Component which placed inside the Form structure without passing through props.
+
+```jsx
+import { useFormApi, useFormState, useFieldApi, useFieldState } from '@douyinfe/semi-ui';
+```
+
+#### useFormApi
+
+`useFormApi` allows you to directly access the formApi of the parent Form component within Functional Component via hook
+
+```jsx live=true dir="column"
+import React from 'react';
+import { useFormApi, Form, Button } from '@douyinfe/semi-ui';
+
+class UseFromApiDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFormApi = () => {
+            const formApi = useFormApi();
+            const change = () => {
+                formApi.setValue('name', Math.random());
+            };
+            return (
+                <Button onClick={change}>ChangeName By【formApi】</Button>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <ComponentUsingFormApi />
+            </Form>
+        )
+    }
+}
+```
+
+#### useFormState
+
+`useFormState` allows you to directly access the form State of the parent Form component within Functional Component via hook
+
+```jsx live=true dir="column"
+import React from 'react';
+import { useFormState, Form } from '@douyinfe/semi-ui';
+
+class UseFromStateDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <pre>
+                    <code>{JSON.stringify(formState)}</code>
+                </pre>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <h5>FormState read by 【useFormState】:</h5>
+                <ComponentUsingFormState />
+            </Form>
+        );
+  }
+}
+```
+
+#### useFieldApi
+
+`useFieldApi` allows you to call the api of the specified Field directly within Functional Component via hook
+
+```jsx live=true dir="column"
+import React from 'react';
+import { useFieldApi, Form, Button } from '@douyinfe/semi-ui';
+
+class UseFieldApiDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFieldApi = () => {
+            const nameFieldApi = useFieldApi('name');
+            const change = () => {
+                nameFieldApi.setValue(Math.random());
+            };
+            return (
+                <Button onClick={change}>Click Me!!! changeNameBy【fieldApi】</Button>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <ComponentUsingFieldApi />
+            </Form>
+        )
+    }
+}
+```
+
+#### useFieldState
+
+`useFieldState` allows you to directly access the State of the specified Field within Functional Component via hook
+
+```jsx live=true dir="column"
+import React from 'react';
+import { useFieldState, Form } from '@douyinfe/semi-ui';
+
+class UseFieldStateDemo extends React.Component {
+  constructor() { super(); }
+  render() {
+    const ComponentUsingFieldState = props => {
+        const fieldState = useFieldState(props.field);
+        return (
+            <>
+              <span>【{props.field}】FieldState read by 【useFieldState】:</span>
+              <code>{JSON.stringify(fieldState)}</code>
+            </>
+        );
+    };
+    return (
+       <Form>
+            <Form.Input field='name' initValue='mike'></Form.Input>
+            <ComponentUsingFieldState field='name' />
+            <Form.Input field='country' initValue='china'></Form.Input>
+            <ComponentUsingFieldState field='country' />
+      </Form>
+    )
+  }
+}
+```
+
+### Use of HOC
+
+We provided two HOC: `withFormApi`、`withFormState`, you can access the API of the Form and the internal state within other components  
+Provided HOC: `withField`, to encapsulating custom components as Field that conform the Semi Form data flow.
+
+```jsx
+import { withFormApi, withFormState, withField } from '@douyinfe/semi-ui';
+```
+
+#### HOC - withFormApi
+
+You can encapsulate the component via `withFormApi` HOC so that the formApi of the parent Form component can be called directly inside the component  
+Note that the encapsulated components must be placed inside the Form structure.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { withFormApi, Form, Button } from '@douyinfe/semi-ui';
+
+class withFormApiDemo extends React.Component {
+    constructor() {
+        super();
+    }
+    renderComponentWithFormApi() {
+        const SomeComponetInsideForm = props => (
+            <Button onClick={() => {
+                props.formApi.setValue('name', Math.random());
+            }}>Click Me!!! ChangeName By【formApi】</Button>
+        );
+        return ComponentWithFormApi = withFormApi(SomeComponetInsideForm);
+
+    }
+    render() {
+        const ComponentWithFormApi = this.renderComponentWithFormApi();
+        return (
+            <Form>
+                <Form.Input field='name' label='Name' initValue='steve'></Form.Input>
+                <Form.Input field='familyName' label='FamilyName' initValue='jobs'></Form.Input>
+                <Button htmlType='submit'>submit</Button>
+                <ComponentWithFormApi />
+            </Form>
+        );
+    }
+}
+```
+
+#### HOC - withFormState
+
+You can encapsulate the component via `withFormState` HOC so that the component has direct access to the Form State of the parent Form component.  
+Note that the encapsulated components must be placed inside the Form structure.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { withFormState, Form } from '@douyinfe/semi-ui';
+
+class withFormStateDemo extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        const SomeComponentInsideForm = props => (
+            <code>{JSON.stringify(props.formState)}</code>
+        );
+        const ComponentWithFormState = withFormState(SomeComponentInsideForm);
+
+        return (
+            <Form>
+                <Form.Input field='name' label='Name' initValue='steve'></Form.Input>
+                <Form.Input field='familyName' label='FamilyName' initValue='jobs'></Form.Input>
+                <ComponentWithFormState />
+            </Form>
+        );
+    }
+}
+```
+
+### With Field encapsulation custom form control
+
+Via `withField`, you can extend other custom components into Field. Form will taking over its behavior.
+
+Note: Custom components must be controlled components.
+
+With Field did the following things.
+
+-   Take over the `value` of the component (or other properties specified by valueKey), `onChange` (or other callback functions specified by onKeyChangeFnName)
+-   Insert Field's `<Form.Label>`above the field
+-   Insert Field's `<ErrorMessage>` under the field
+
+With Field Options specific configuration can be consulted [withFieldOption](#WithFieldOptions)
+
+```jsx
+withField(YourComponent, withFieldOptions);
+```
+
+```jsx live=true dir="column"
+import React from 'react';
+import { withField, Form } from '@douyinfe/semi-ui';
+
+class CustomFieldDemo extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        // Here to encapsulat HTML input
+        const htmlInput = (props) => {
+            let value = props.value || '';
+            let { validateStatus, ...rest } = props; // prevent props being transparently transmitted to DOM
+            return <input {...rest} value={value} />; 
+        };
+        const CustomInput = withField(htmlInput, { valueKey: 'value', onKeyChangeFnName: 'onChange', valuePath: 'target.value' });
+
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <pre>
+                    <code>{JSON.stringify(formState.values)}</code>
+                </pre>
+            );
+        };
+        return (
+            <Form>
+                <CustomInput field='name' />
+                <ComponentUsingFormState />
+            </Form>
+        );
+    }
+}
+```
+
+## API reference
+
+## Form Props
+
+| Properties        | Instructions                                                                                                                                                                                                                                                                                                        | Type                                            | Default    |
+| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ---------- |
+| getFormApi        | This function will be executed once when the form is mounted and returns formApi. <br/>formApi can be used to modify the internal state of the form (value, touched, error)                                                                                                                                         | function (formApi: object)                      |            |
+| initValues        | Used to uniformly set the initial value of the form <br/>(will be consumed only once when form is mount)                                                                                                                                                                                                            | object                                          |            |
+| onChange          | Callback invoked when form update, including Fields mount/unmount / value change / <br/> blur / validation status change / error status change.                                                                                                                                                                     | function (formState: object)                    |            |
+| onValueChange     | Callback invoked when form values update                                                                                                                                                                                                                                                                            | function (values: object, changedValue: object) |
+| onReset           | Callback invoked after clicked on reset button or executed `formApi.reset()`                                                                                                                                                                                                                                        | function ()                                     |            |
+| onSubmit          | Callback invoked after clicked on submit button or exected `formApi.submit()`, <br/>and all validation pass.                                                                                                                                                                                                        | function (values: object)                       |            |
+| onSubmitFail      | Callback invoked after clicked on submit button or exected `formApi.submit()`,<br/> but validate failed.                                                                                                                                                                                                            | function (object, values: object)               |            |
+| validateFields    | Form-level custom validate functions are called at submit or formApi.validate(). <br/>Supported synchronous / asynchronous function                                                                                                                                                                                 | function (values)                               |            |
+| component         | For declaring fields, not used at the same time as render, props.children                                                                                                                                                                                                                                           | ReactNode                                       |
+| render            | For declaring fields, not used at the same time as component, props.children                                                                                                                                                                                                                                        | function                                        |
+| allowEmpty        | Whether to keep the key of the null field in the values, keep the key when true, and remove the key when false    | boolean                                         | false      |
+| layout            | The layout of fields, optional `horizontal` or `vertical`                                                                                                                                                                                                                                                           | string                                          | 'vertical' |
+| labelPosition     | Location of label in Field, optional 'top', 'left', 'inset' <br/> (inset label only partial component support)                                                                                                                                                                                                      | string                                          | 'top'      |
+| labelWidth        | Width of field'r label                                                                                                                                                                                                                                                                                              | string\|number                                  |            |
+| labelAlign        | Text-align value of label                                                                                                                                                                                                                                                                                           | string                                          | 'left'     |
+| className         | Classname for form tag                                                                                                                                                                                                                                                                                              | string                                          |
+| wrapperCol        | Uniformly apply the layout on each Field, with [Col component](/en-US/basic/grid#Col), <br/>set `span`, `span` values, such as {span: 20, selected: 4}                                                                                                                                     | object                                          |
+| labelCol          | Uniformly applied to the label label layout of each Field, with [Col Component](/en-US/basic/grid#Col), <br/>set `span`, `span` values, such as {span: 6, selected: 2}                                                                                                                     | object                                          |
+| autoScrollToError | If setting true,when submit or call formApi.validate () fails verification, it will automatically scroll to the wrong field, object config refer to [options](https://github.com/stipsan/scroll-into-view-if-needed#options)                                                                                       | boolean\| object                                | false      |
+| disabled          | If true, all fields inside the form structure will automatically inherit the disabled attribute                                                                                                                                                                                                                     | boolean                                         | false      |
+| showValidateIcon  | Whether the verification information block in the field automatically adds the corresponding status icon display <br/>**since v1.0.0**                                                                                                                                                                              | boolean                                         | true       |
+| extraTextPosition | The extraTextPosition property applied to each Field uniformly controls the display position of extraText. Middle (the vertical direction is displayed in the order of Label, extraText, and Field), bottom (the vertical direction is displayed in the order of Label, Field, and extraText) <br/>**since v1.9.0** | string                                          | 'bottom'   |
+
+## FormState
+
+FormState stores all the state values within the Form, including the values of each field, error information, touched status
+
+| Name    | Instructions                                                                                                                     | Initial value | Example                       |
+| ------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | ----------------------------- |
+| values  | Value Collection of the form                                                                                                     | {}            | {fieldA: 'str', fieldB: true} |
+| errors  | Form error information collection, you can decide whether to allow users to submit by judging whether there is error information | {}            | {fieldA: 'length not valid'}  |
+| touched | The collection of fields the user has clicked on                                                                                 | {}            | {fieldA: true}                |
+
+### How to access the form state
+
+-   By calling `formApi.getFormState()`
+-   By declaring fields through "child render function", formState will injected as a parameter
+-   By declaring fields through "render props", formState will injected as a parameter
+-   Via [useFormState](#useFormState) hook
+-   Via withFormState HOC
+
+## FormApi
+
+We provide FormApi. You have easy access to FormApi both inside and outside the Form, which allows you to use getter and setter to get and manipulate the values of FormState.  
+The table below describes the features available in the formApi.
+
+| Function      | Description                                                                                                                                                                                                                                                                                                                        | example                                                                                                                       |
+| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| getFormState  | Get FormState                                                                                                                                                                                                                                                                                                                      | formApi.getFormState()                                                                                                        |
+| submitForm    | manually submit the submit operation                                                                                                                                                                                                                                                                                               | formApi.submitForm()                                                                                                          |
+| reset         | reset the form manually                                                                                                                                                                                                                                                                                                            | formApi.reset()                                                                                                               |
+| validate      | Manually trigger validation of the entire form                                                                                                                                                                                                                                                                                     | formApi.validate() <br/>.then(values ​​=> {})<br/>.catch(errors => {})                                                        |
+| setValues ​​  | Set the values ​​of the entire form. The isOverride in the second parameter is false by default. <br/> By default, only the values ​​of the existing field in the Form are updated from `newValues` to`formState.values`. <br/> When isOverride is `true`, the newValues ​​will be overwritten and assigned to formState.values ​​ | formApi.setValues(newValues: object, {isOverride: boolean})                                                                   |
+| getValues ​​  | Get the values of all Field                                                                                                                                                                                                                                                                                                        | formApi.getValues()                                                                                                           |
+| setValue      | provides direct modification of formState.values ​​method.<br/>The difference from `setValues` ​​is that it only modifies a single field.                                                                                                                                                                                          | formApi.setValue(field: string, newFieldValue: any)                                                                           |
+| getValue      | Get the value of all / single Field                                                                                                                                                                                                                                                                                                | formApi.getValue()<br/>formApi.getValue(field: string)                                                                         |
+| setTouched    | modify formState.touched                                                                                                                                                                                                                                                                                                           | formApi.setTouched(field: string, isTouched: boolean)<br/>                                                                    |
+| getTouched    | Get the touched state of the Field                                                                                                                                                                                                                                                                                                 | formApi.getTouched(field: string)                                                                                             |
+| setError      | Modify the error information of a field                                                                                                                                                                                                                                                                                            | formApi.setError(field: string, fieldErrorMessage: string)                                                                    |
+| getError      | Get Error Status of Field                                                                                                                                                                                                                                                                                                          | formApi.getError(field: string)                                                                                               |
+| getFieldExist | Get whether the field exists in the Form                                                                                                                                                                                                                                                                                           | formApi.getFieldExist(field: string)                                                                                          |
+| scrollToField | Scroll to field                                                                                                                                                                                                                                                                                                                    | formApi.scrollToField(field: string, scrollOpts: [object](<(https://github.com/stipsan/scroll-into-view-if-needed#options)>)) |
+
+### How to access formApi
+
+-   The Form component in the ComponentDidMount phase will execute the getFormApi callback passed in by props. You can save a reference to formApi in the callback function for subsequent calls (example code below)
+    In addition, we provide other ways to get formApi, and you can choose different ways of calling according to your preference.
+-   Use reference to get form instance,you can access form instance & its formApi
+-   By declaring fields through "child render function", formApi will injected as a parameter
+-   By declaring fields through "render props", formApi will injected as a parameter
+-   Via [useFormApi](#useFormApi) hook
+-   Via "withFormApi" HOC
+
+```jsx
+class FormApiDemo extends React.Component {
+    constructor() {
+        super();
+        this.getFormApi = this.getFormApi.bind(this);
+        this.formBRef = React.createRef();
+    }
+    getFormApi(formApi) {
+        this.formApi = formApi;
+        // After getting the formApi object, you can use it to make any changes you want to the form
+    }
+
+    changeValues() {
+        // use formApi to update formA
+        this.formApi.setValues({ a: 1});
+        // use formApi to update formB
+        this.formBRef.current.formApi.setValues({ b: 2});
+    }
+
+    render() {
+        return
+            (
+                <Form getFormApi={this.getFormApi} />
+                <Form ref={this.formBRef} />
+                <Button onClick={()=>this.changeValues()}>Change</Button>
+            )
+    }
+}
+```
+
+```jsx
+() => {
+    // functional compoentn usage
+    const api = useRef();
+
+    return (<Form getFormApi={formApi => api.current = formApi}>
+        <Form.Input field='a' />
+        <Button onClick={()=>{console.log(api)}}>log</Button>
+    </Form>)
+}
+```
+## Field Props
+
+<Notice type="primary" title="About Field ref">
+    Versions before v1.30.0, the Field component will not do ref forwarding<br/>
+    After v1.30, the underlying component instance can be obtained directly through ref, such as specifying ref to Form.Input and Form.Select, and directly obtaining the ref reference of the underlying original Input and Select components
+</Notice>
+
+| Properties            | Description                                                                                                                                                                                                                              | Type                                   | Default   | Examples                                                           |
+| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | --------- | ------------------------------------------------------------------ |
+| field                 | The mapping path of the field's value in formState.values. Form will use this value to distinguish the internal form control. <br/> **Required!!!**                                                                                      | string                                 |           |                            |
+| label                 | The label text for this field. When not passed, it defaults to the same name as field                                                                                                                                                    | string                                 |           |
+| labelPosition         | Label position of this field, optional 'top' / 'left' / 'inset'                                                                                                                                                                          | string                                 |           |
+| labelAlign            | Text-align of the label text of this field                                                                                                                                                                                               | string                                 |           |
+| labelWidth            | The width of the label text of this field                                                                                                                                                                                                | string\|number                         |           |
+| noLabel               | When you don't need to add label automatically, you can set this value to true                                                                                                                                                           | boolean                                |           |
+| name                  | Field name. When passed in, the corresponding className will be automatically added to the corresponding field div, such as: money => '.semi-form-field-money'                                                                           | string                                 |           |
+| fieldClassName        | The className of the entire fieldWrapper is the same as the name parameter, except that the prefix is ​​not automatically appended                                                                                                       | string                                 |           |
+| fieldStyle            | The inline style of the entire fieldWrapper <br/>**since v1.9.0**                                                                                                      | object                                 |           |
+| initValue             | The initial value of the field (consumed only once when Field mounted, subsequent updates are invalid), it has higher priority than the values ​​in Form's initValues ​​                                                                 | any(type depends on current component) |           |
+| validate              | The custom validation function for this form control. Supports synchronous and asynchronous verification. <br/> Rules does not take effect when validate is set                                                                           | function(fieldValue, values)           |           | (fieldValue) => fieldValue.length>5? 'error balabala': ''          |
+| rules                 | validation rules, validation library based on [async-validator](https://github.com/yiminghe/async-validator)                                                                                                                             | array                                  |           | const rules = \[{type:' string ', message:' invalidate string'} \] |
+| validateStatus        | The validation result status of this form control, optional: `success` / `error` / `warning` / `default`                                                                                                                                 | string                                 | 'default' |
+| trigger               | The timing of triggering the verification, optional: `blur` / `change` / `custom` / `mount` <br/> 1. When set to custom, only formApi will trigger the verification <br/> 2。mount (triggered once when mounting)                          | string                                 | 'change'  |
+| onChange              | Callback invoked when this field value changes                                                                                                                                                                                           |
+| transform             | transofrm field values before validation                                                                                                                                                                                                 | function(fieldValue)                   |           | (value) => Number(value)                                           |
+| allowEmptyString      | Whether to allow values to be empty strings. <br/>When the value is '' by default, the key corresponding to this field will be removed from `values`. <br/>If you want to keep the key, you need to set allowEmptyString to true           | boolean                                |           | false                                                              |
+| convert               | After the field value changes, before rerender, update the value of filed                                                                                                                                                                | function(fieldValue)                   |           | (value) => newValue(value)                                         |
+| stopValidateWithError | When it is true, the rules check is used. After encountering the first rule that fails the check, it will no longer trigger the check of subsequent rules<br/>**since v0.35.0**                                                          | boolean                                |           | false                                                              |
+| helpText              | Custom prompt information, which is displayed in the same block as the verification information. When both have values, the verification information is displayed first<br/>**since v1.0.0**                                             | ReactNode                              |           |                                                                    |
+| extraText             | Additional prompt information, you can use this when both error information and prompt copy are required, after helpText/errorMessage<br/>**since v1.0.0**                                                                               | ReactNode                              |           |                                                                    |
+| pure                  | Whether to only take over the data stream, when true, it will not automatically insert modules such as ErrorMessage, Label, extraText, etc. The style and DOM structure are consistent with the original components<br/>**since v1.1.0** | boolean                                | false     |                                                                    |
+| extraTextPosition     | controls the display position of extraText. Middle (the vertical direction is displayed in the order of Label, extraText, and Field), bottom (the vertical direction is displayed in the order of Label, Field, and extraText) <br/>**since v1.9.0** | string                                | 'bottom'     |                                                                    |
+| ...other              | The other configurable properties of the component can be passed in together with the above properties, such as the size / placeholder of Input,**Field passes it to the component itself**                                             |
+
+## Field Api
+
+We also provide `fieldApi`, most of which is similar to `formApi`, with the difference that fieldApi limits the scope of modification, and it can only modify the bound field
+
+| Function   | Instructions                                      | example                                    |
+| ---------- | ------------------------------------------------- | ------------------------------------------ |
+| setValue   | Modify the value of the current Field             | fieldApi.setValue(newValue: any)           |
+| getValue   | Gets the value of the current Field               | fieldApi.getValue()                        |
+| setTouched | Modify the value of the current Field             | fieldApi.setTouched(true)                  |
+| getTouched | Get Field's status                                | fieldApi.getTouched()                      |
+| setError   | Modify the error information of the current Field | fieldApi.setError(newErrorMessage: string) |
+| getError   | Gets field's error status                         | fieldApi.getError()                        |
+
+## Form.Section
+
+> Form.Section is available since v1.0.0
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Section } = Form;
+```
+
+| Properties | Instructions       | Type      |
+| ---------- | ------------------ | --------- |
+| text       | Title of section   | ReactNode |
+| className  | Classname          | string    |
+| style      | Inline style       | object    |
+| children   | Content of section | ReactNode |
+
+## Form.Label
+
+By default, `Label` is self-inserted into each `Field` by `Form`.  
+If you need to self-insert Label elsewhere, we have provided the `Label` component for you.
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Label } = Form;
+```
+
+| Properties | Instructions                    | Type      | Default |
+| ---------- | ------------------------------- | --------- | ------- |
+| text       | Label content                   | ReactNode |         |
+| required   | Whether to show the required \* | boolean   | false   |
+| extra      | Content after required          | ReactNode |         |
+| align      | Text-align                      | string    | 'left'  |
+| className  | Classname of label wrapper      | string    |         |
+| style      | Inline style                    | string    |         |
+| width      | Label width                     | number    |         |
+
+## Form.Slot
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Slot } = Form;
+```
+
+| Properties | Instructions                                                                                                                                                                                            | Type           | Default |
+| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------- |
+| label      | Slot's [Label configuration](#Form.Label), for example {text: 'semi', align: 'left'}; can also be passed directly into string, inside the Slot will be automatically encapsulated in legal Label format | object\|string |         |
+| className  | Classname of Slot Wrappper                                                                                                                                                                              | string         |         |
+| style      | Slot inline style                                                                                                                                                                                       | object         |         |
+| children   | Content of slot. You can place your custom component here                                                                                                                                               | ReactNode      |         |
+
+## Form.ErrorMessage
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { ErrorMessage } = Form;
+```
+
+-   When the error is React Node, String, boolean, render directly
+-   When the error is an array, the join operation is automatically performed to aggregate the error information in the array
+
+| Properties | Instructions                      | Type                     | Default |
+| ---------- | --------------------------------- | ------------------------ | ------- |
+| error      | Error message content             | string\|array\|ReactNode\|undefined\|boolean | {}      |
+| className  | Classname of ErrorMessage wrapper | string                   |         |
+| style      | Inline style                      | object                   |         |
+
+## withFieldOptions
+
+| key               | Description                                                                                                                                                                                                                                                                                                                                                                 | Default    |
+| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| valueKey          | The component represents the property of the value, such as Switch, Radio is' checked 'and Input is' value '                                                                                                                                                                                                                                                                | 'value'    |
+| onKeyChangeFnName | The callback function when the component value changes, generally 'onChange'                                                                                                                                                                                                                                                                                                | 'onChange' |
+| valuePath         | The path of the value attribute to the first parameter in the callback function, such as Radio's onChange (e.target. checked), then the value needs to be set to target .checkd; Radio Group's onChange (e.target. value), which is' target .value '; if the first parameter is the value itself, there is no need to take the value down, the item does not need to be set |            |
+| withCursor        | Do you need to maintain a cursor for Input class components                                                                                                                                                                                                                                                                                                                 | false      |
+| shouldMemo        | Do you need memo (for form performance optimization to avoid Field being rerender when Formrerender), for custom components with internal states that may update and affect the UI, this item should be set false                                                 | true       |
+
+## Design Tokens
+
+<DesignToken/>
+
+## FAQ
+
+-   **Why did I declare the form, modify the value, and the data is not automatically mapped to formState.values?**  
+    Check that the field has been passed correctly, and the `field` attribute on the Field component is a must-fill property !
+
+-   **Why doesn't the passed `defaultValue` or `defaultChecked` take effect?**  
+    Refer to the beginning of the document [Field](#Field). The Form.Field component unifies the default value. You should pass the default value using `initValue` or `initValues`
+
+-   **Why did the component not change and the value not take effect after `initValue` and `initValues` were updated asynchronously?**  
+    `initValue`, `initValues` are only consumed once when Field and Form mount, and subsequent asynchronous updates will not take effect.  
+    If your initial value needs to be taken remotely, you can update it using `formApi.setValue / setValues` after you get the value  
+    Or send a new `key` directly to Form or Field to force it to remount.
+
+-   **Why can't getValues get a certain field?**
+
+    If the field has no initial value, `getValues` cannot get this item. You can set `initValues`/`initValue` or set the `allowEmpty` attribute to the form.
+
+-   **[🔍 🧾 More FAQ](https://bytedance.feishu.cn/docs/doccnNKaGhZMqyu0FufD1JGHOjf)**

+ 2094 - 0
content/input/form/index.md

@@ -0,0 +1,2094 @@
+---
+localeCode: zh-CN
+order: 20
+category: 输入类
+title:  Form 表单
+icon: doc-form
+dir: column
+---
+
+
+## 表单(Form)
+
+-   **按需重绘**,避免了不必要的全量渲染, 性能更高
+-   简单易用,**结构简洁**,避免了不必要的层级嵌套
+    **无需 Form.create()、无需 Form.item,无需 getFieldDecorator()**
+-   在 Form 外部可方便地获取 formState / fieldState  
+    提供在外部对表单内部进行操作的方法:formApi / fieldApi
+-   支持将自定义组件封装成表单控件,你可以通过 Form 提供的扩展机制(withField HOC)快捷接入自己团队的组件
+-   支持 Form level/Field level 级别的赋值、校验(同步/异步)
+
+## 表单控件(Field)
+
+Semi 将所有自带的输入控件(文本输入框、下拉选择、复选框、单选框等)都使用 withField 封装了一次。
+接管了他们的数据流(value & onChange)  
+使用的时候,需要从 Form 中导出(注意:从 Form 导出的控件才具有数据同步功能)
+
+#### 目前 Form 提供了如下表单控件
+
+-   `Input`、`InputNumber`、`TextArea`、`Select`、`Checkbox`、`Radio`、`RadioGroup`、`Switch`、`DatePicker`、`TimePicker`、`Slider`、`InputGroup`、`TreeSelect`、`Cascader`、`Rating`、`AutoComplete`、`Upload`、`Label`、`ErrorMessage`、`Section`、`TagInput`
+    都挂载在 Form 下,使用时直接以<Form.Input\> 、<Form.Select\>声明即可
+
+```javascript import
+import { Form } from '@douyinfe/semi-ui';
+// 具有数据同步功能的表单控件,在<Form></Form>内使用时,数据流会被Form自动接管
+// 从Form中导出表单控件时,你还可以进行重命名(这里命名为FormInput仅仅是为了在以下示例中跟普通Input做区分)
+const FormInput = Form.Input;
+const FormSelect = Form.Select;
+const Option = FormSelect.Option;
+// 普通Input,在<Form></Form>内部使用时,Form不会对其做任何处理
+import { Input } from '@douyinfe/semi-ui';
+```
+
+Form 提供的 Field 级别组件,它的 value(或者 valueKey 指定的其他属性)、onChange(或 onKeyChangeFnName 指定的其他回调函数)
+属性都会被 Form 劫持,所以
+
+<Notice type="primary" title="注意事项">
+<div>1. 你不需要也不应该用 onChange 来作同步,当然你可以继续监听 onChange 事件获取最新的值</div>
+<div>2. 你不能再用控件的`value`、`defaultValue`、`checked`、`defaultChecked`等属性来设置表单控件的值,默认值可以通过 Field 的`initValue`或者 Form 的`initValues`设置</div>
+<div>3. 你不应该直接修改 FormState 的值,所有对 Form 内数据的修改都应该通过提供的formApi、fieldApi来完成</div>
+</Notice>
+
+## 代码演示
+
+### 声明表单的多种写法
+
+Semi Form 同时支持多种写法
+
+#### 基本写法
+
+给表单控件添加`field`属性即可  
+还可以给每个表单控件设置`label`属性,不传入时默认与 field 相同
+
+<Notice type='primary' title='注意事项'>
+对于Field级别组件来说,field 属性是必填项!
+</Notice>
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+import { IconHelpCircle } from '@douyinfe/semi-icons';
+
+() => {
+    const { Option } = Form.Select;
+
+    return (
+        <Form layout='horizontal'  onValueChange={values=>console.log(values)}>
+            <Form.Select field="Role" label='角色' style={{width:176}}>
+                <Option value="admin">管理员</Option>
+                <Option value="user">普通用户</Option>
+                <Option value="guest">访客</Option>
+            </Form.Select>
+            <Form.Input field='UserName' label='用户名' style={{width:80}}/>
+            <Form.Input field='Password' label={{ text: '密码', extra: <IconHelpCircle /> }} style={{width:176}}/>
+        </Form>
+    )
+}
+```
+
+#### 支持的其他写法
+
+当你需要在 Form 结构内部直接获取到 `formState`、`formApi`、`values` 等值时,你还可以使用以下的写法
+
+#### 通过 render 属性传入
+
+即 render props
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => {
+    return (
+        <Form render={({ formState, formApi, values }) => (
+            <>
+                <Form.Select field="Role" label='角色' style={{width:176}}>
+                    <Form.Select.Option value="admin">管理员</Form.Select.Option>
+                    <Form.Select.Option value="user">普通用户</Form.Select.Option>
+                    <Form.Select.Option value="guest">访客</Form.Select.Option>
+                </Form.Select>
+                <Form.Input field='UserName' label='用户名' style={{width:80}}/>
+                <Form.Input field='Password' label='密码' style={{width:176}}/>
+                <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+            </>
+        )} layout='horizontal' onValueChange={values=>console.log(values)}>
+        </Form>
+    )
+}
+
+```
+
+#### 通过 child render function
+
+Form 的 children 是一个 function,return 出所有表单控件
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => {
+    return (
+        <Form layout='horizontal' onValueChange={values=>console.log(values)}>
+            {
+                ({ formState, values, formApi }) => (
+                    <>
+                        <Form.Select field="Role" label='角色' style={{width:176}}>
+                            <Form.Select.Option value="admin">管理员</Form.Select.Option>
+                            <Form.Select.Option value="user">普通用户</Form.Select.Option>
+                            <Form.Select.Option value="guest">访客</Form.Select.Option>
+                        </Form.Select>
+                        <Form.Input field='UserName' label='用户名' style={{width:80}} />
+                        <Form.Input field='Password' label='密码' style={{width:176}}/>
+                        <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+                    </>
+                )
+            }
+        </Form>
+    )
+}
+```
+
+#### 通过 props.component
+
+通过 component 属性直接将整个内部结构以 ReactNode 形式传入
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => {
+    const fields = ({ formState, formApi, values }) => (
+          <>
+              <Form.Input field='Role' style={{width:176}}/>
+              <Form.Input field='UserName' style={{width:80}}/>
+              <Form.Input field='Password' style={{width:176}}/>
+              <code style={{marginTop: 30}}>{JSON.stringify(formState)}</code>
+          </>
+    );
+    return <Form component={fields} layout='horizontal' onValueChange={values=>console.log(values)}/>
+}
+```
+
+### 已支持的表单控件
+
+> Form.TreeSelect、Form.Cascader、Form.Rating 在 v0.22.0 及之后的版本开始提供;  
+> Form.AutoComplete 在 v0.28.0 及之后的版本开始提供  
+> Form.Upload 在 v1.0.0 及之后的版本开始提供  
+> Form.TagInput 在 v1.21.0 及之后的版本开始提供  
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Col, Row, Button } from '@douyinfe/semi-ui';
+class BasicDemoWithInit extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            initValues: {
+                name: 'semi',
+                business: ['ulikeCam'],
+                role: 'ued',
+                switch: true,
+                files: [
+                    {
+                        uid: '1',
+                        name: 'vigo.png',
+                        status: 'success',
+                        size: '130KB',
+                        preview: true,
+                        url: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/vigo.png'
+                    },
+                    {
+                        uid: '2',
+                        name: 'tiktok.png',
+                        status: 'validateFail',
+                        size: '222KB',
+                        preview: true,
+                        url: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/tiktok.png'
+                    },
+                    {
+                        uid: '3',
+                        name: 'jiafang.jpeg',
+                        status: 'uploading',
+                        size: '222KB',
+                        percent: 50,
+                        preview: true,
+                        fileInstance:  new File([new ArrayBuffer(2048)], 'jiafang.jpeg', { type: 'image/jpeg' }),
+                        url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg'
+                    }
+               ]
+            }
+        };
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi }
+
+    render() {
+        const { Section, Input, InputNumber, AutoComplete, Select, TreeSelect, Cascader, DatePicker, TimePicker, TextArea, CheckboxGroup, Checkbox, RadioGroup, Radio, Slider, Rating, Switch, TagInput } = Form;
+        const { initValues } = this.state;
+        const plainOptions = ['A', 'B', 'C'];
+        const style = { width: '90%' };
+        const treeData = [
+            {
+                label: '亚洲',
+                value: 'Asia',
+                key: '0',
+                children: [
+                    {
+                        label: '中国',
+                        value: 'China',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: '北京',
+                                value: 'Beijing',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: '上海',
+                                value: 'Shanghai',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: '北美洲',
+                value: 'North America',
+                key: '1',
+            }
+        ];
+
+        return (
+            <Form
+                getFormApi={this.getFormApi}
+                initValues={initValues}
+                style={{ padding: 10, width: '100%' }}
+                onValueChange={(v)=>console.log(v)}
+            >
+                <Section text={'基本信息'}>
+                    <Row>
+                        <Col span={12}>
+                            <Input
+                                field="name"
+                                label="名称(Input)"
+                                initValue={'mikeya'}
+                                style={style}
+                                trigger='blur'
+                            />
+                        </Col>
+                        <Col span={12}>
+                            <DatePicker field="date" label='日期(DatePicker)' style={style} initValue={new Date()} placeholder='请选择生效日期' />
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                            <Select field="role" style={style} label='角色(Select)' placeholder='请选择你的角色'>
+                                <Select.Option value="operate">运营</Select.Option>
+                                <Select.Option value="rd">开发</Select.Option>
+                                <Select.Option value="pm">产品</Select.Option>
+                                <Select.Option value="ued">设计</Select.Option>
+                            </Select>
+                        </Col>
+                        <Col span={12}>
+                            <Select
+                                field="business"
+                                multiple
+                                style={style}
+                                placeholder='请选择业务线'
+                                label="业务线(多选Select)"
+                                extraText={
+                                    <div style={{
+                                        color: 'rgba(var(--semi-blue-5), 1)',
+                                        fontSize: 14,
+                                        userSelect: 'none',
+                                        cursor: 'pointer'
+                                    }}>
+                                        没有找到合适的业务线?
+                                    </div>
+                                }
+                            >
+                                <Select.Option value="tiktok">抖音</Select.Option>
+                                <Select.Option value="ulikeCam">轻颜相机</Select.Option>
+                                <Select.Option value="toutiao">今日头条</Select.Option>
+                            </Select>
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                            <Form.Cascader
+                                placeholder="请选择所在地区"
+                                treeData={treeData}
+                                field='area'
+                                label='地区(Cascader)'
+                                style={style}
+                            >
+                            </Form.Cascader>
+                        </Col>
+                        <Col span={12}>
+                            <Form.TreeSelect
+                                field="tree"
+                                style={style}
+                                label='节点(TreeSelect)'
+                                placeholder='请选择服务节点'
+                                treeData={treeData}
+                                filterTreeNode
+                            >
+                            </Form.TreeSelect>
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                            <TagInput 
+                                field="product"
+                                label='产品(TagInput)'
+                                defaultValue={['tiktok','ulikeCam']}
+                                placeholder='请输入产品'
+                                style={style}
+                            />
+                        </Col>
+                    </Row>
+                    <Row>
+                      <Col span={24}>
+                        <Form.Upload
+                            field='files'
+                            label='证明文件(Upload)'
+                            action='//semi.design/api/upload'
+                        >
+                            <Button icon={<IconUpload />} theme="light">
+                                点击上传
+                            </Button>
+                        </Form.Upload>
+                      </Col>
+                    </Row>
+                 </Section>
+                 <Section text='资源详情'>
+                    <Row>
+                        <Col span={12}>
+                            <TextArea
+                                style={{ ...style, height: 120 }}
+                                field='description'
+                                label='申请理由(TextArea)'
+                                placeholder='请填写申请资源理由'
+                            />
+                        </Col>
+                        <Col span={12}>
+                            <CheckboxGroup
+                                field="type"
+                                direction='horizontal'
+                                label='申请类型(CheckboxGroup)'
+                                initValue={['user', 'admin']}
+                                rules={[
+                                    { required: true }
+                                ]}
+                            >
+                                <Checkbox value="admin">admin</Checkbox>
+                                <Checkbox value="user">user</Checkbox>
+                                <Checkbox value="guest">guest</Checkbox>
+                                <Checkbox value="root">root</Checkbox>
+                            </CheckboxGroup>
+                            <RadioGroup field="isMonopolize" label='是否独占资源(Radio)' rules={[
+                                { type: 'boolean' },
+                                { required: true, message: '必须选择是否独占 ' }
+                            ]}>
+                                <Radio value={true}>是</Radio>
+                                <Radio value={false}>否</Radio>
+                            </RadioGroup>
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                        <TimePicker field="time" label='截止时刻(TimePicker)' style={{ width: '90%' }}/>
+                        </Col>
+                        <Col span={12}>
+                            <InputNumber field='number' label='申请数量(InputNumber)' initValue={20} style={style}/>
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                        <Slider field="range" label='资源使用报警阈值(%)(Slider)' initValue={10} style={{ width: '90%' }}/>
+                        </Col>
+                        <Col span={12}>
+                        <Switch field='switch' label='开关(Switch)'/>
+                        </Col>
+                    </Row>
+                    <Row>
+                        <Col span={12}>
+                        <Rating field="rating" label='满意度(Rating)' initValue={2} style={{ width: '90%' }}/>
+                        </Col>
+                    </Row>
+                </Section>
+                <Checkbox value="false" field="agree" noLabel={true}>
+                    我已阅读并清楚相关规定(Checkbox)
+                </Checkbox>
+                <Button type="primary" htmlType="submit" className="btn-margin-right">提交(submit)</Button>
+                <Button htmlType="reset">重置(reset)</Button>
+            </Form>
+        );
+    }
+}
+```
+
+### 表单控件值的绑定
+
+每个表单控件都需要以`field`属性绑定一个字段名称,用于将表单项的值正确映射到`FormState` values / errors / touched 中  
+字段可以是简单的字符串,可以是包含`.`或者`[]`的字符串, 支持多级嵌套  
+下面是字段名称以及他们在 FormState 中的映射路径的示例
+
+| Field                  | Resolution                         |
+| ---------------------- | ---------------------------------- |
+| username               | formState.values.username          |
+| user\[0\]              | formState.values.user\[0\]         |
+| siblings.1             | formState.values.siblings\[1\]     |
+| siblings\['2'\]        | formState.values.siblings\[2\]     |
+| parents\[0\].name      | formState.values.parents\[0\].name |
+| parents\[1\]\['name'\] | formState.values.parents\[1\].name |
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Toast, Row, Col, TextArea } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        onSubmit={values => Toast.info({ content: JSON.stringify(values) })}
+    >
+        {
+            ({ formState, values, formApi }) => (
+                <Row>
+                    <Col span={12}>
+                        <Form.Input field='username' placeholder='请尝试输入值'/>
+                        <Form.Input field='user[0]' placeholder='请尝试输入值'/>
+                        <Form.Input field='siblings.1' placeholder='请尝试输入值'/>
+                        <Form.Input field="siblings['2']" placeholder='请尝试输入值'/>
+                        <Form.Input field='parents[0].name' placeholder='请尝试输入值'/>
+                        <Form.Input field="parents[1]['name']" placeholder='请尝试输入值'/>
+                    </Col>
+                    <Col span={10} offset={1} style={{marginTop: 12}}>
+                        <Form.Label text='FormState实时映射值:'></Form.Label>
+                        <TextArea value={JSON.stringify(formState.values)}></TextArea>
+                    </Col>
+                </Row>
+            )
+        }
+    </Form>
+)
+```
+
+### 表单布局
+
+-   垂直布局:表单控件之间上下垂直排列(默认)  
+     Semi Design 更推荐表单采用垂直布局
+
+```jsx live=true dir="column" 
+import React from 'react';
+import { Form, Toast, Button } from '@douyinfe/semi-ui';
+
+() => {
+ const handleSubmit = (values) => {
+   console.log(values);
+   Toast.info('表单已提交');
+ }
+ return (
+     <Form onSubmit={values => handleSubmit(values)} style={{width: 400}}>
+        {({formState, values, formApi}) => (
+            <>
+                <Form.Input field='phone' label='PhoneNumber' style={{ width: '100%' }} placeholder='Enter your phone number'></Form.Input>
+                <Form.Input field='password' label='Password' style={{ width: '100%' }} placeholder='Enter your password'></Form.Input>
+                <Form.Checkbox field='agree' noLabel>I have read and agree to the terms of service</Form.Checkbox>
+                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
+                  <p>
+                      <span>Or</span><Button theme='borderless' style={{ color: 'rgb(101, 178, 252)', marginLeft: 10, cursor:'pointer' }}>Sign up</Button>
+                  </p>
+                  <Button disabled={!values.agree} htmlType='submit' type="tertiary">Log in</Button>
+                </div>
+            </>
+        )}
+    </Form>
+ )
+}
+```
+
+-   水平布局:表单控件之间水平排列
+    你可以通过设置 layout='horizontal'来使用水平布局
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form layout='horizontal'>
+        <Form.Input field='phone' label='PhoneNumber' placeholder='Enter your phone number'></Form.Input>
+        <Form.Input field='password' label='Password' placeholder='Enter your password'></Form.Input>
+    </Form>
+)
+```
+
+-   labelPosition、labelAlign  
+    你可以通过设置 labelPosition、labelAlign 控制 label 在 Field 中出现的位置,文本对齐的方向
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Select } from '@douyinfe/semi-ui';
+
+class BasicDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            labelPosition: 'left',
+            labelAlign: 'left',
+            labelWidth: '180px'
+        };
+        this.changeLabelPos = this.changeLabelPos.bind(this);
+        this.changeLabelAlign = this.changeLabelAlign.bind(this);
+    }
+
+
+    changeLabelPos(labelPosition) {
+        let labelWidth;
+        labelPosition === 'left' ? labelWidth = '180px' : labelWidth = 'auto';
+        this.setState({ labelPosition, labelWidth })
+    }
+
+    changeLabelAlign(labelAlign) { this.setState({ labelAlign }) }
+
+    render() {
+        const { labelPosition, labelAlign, labelWidth } = this.state;
+        return (
+            <>
+            <div style={{borderBottom: '1px solid var(--semi-color-border)', paddingBottom: 12 }}>
+                <Form.Label style={{ marginLeft: 10 }}>切换Label位置:</Form.Label>
+                <Select onChange={this.changeLabelPos} value={labelPosition} style={{width: 200}} insetLabel='labelPosition'>
+                    <Select.Option value='top'>top</Select.Option>
+                    <Select.Option value='left'>left</Select.Option>
+                </Select>
+                <Form.Label style={{ marginLeft: 10 }}>切换Label文本对齐方向:</Form.Label>
+                <Select onChange={this.changeLabelAlign} value={labelAlign} style={{width: 200}} insetLabel='labelAlign'>
+                    <Select.Option value='left'>left</Select.Option>
+                    <Select.Option value='right'>right</Select.Option>
+                </Select>
+            </div>
+            <Form
+                labelPosition={labelPosition}
+                labelWidth={labelWidth}
+                labelAlign={labelAlign}
+                key={labelPosition + labelAlign}
+                style={{ padding: '10px', width: 600 }}>
+                      <Form.Input
+                          field="input"
+                          label="手机号码"
+                          trigger='blur'
+                          style={{width: 200}}
+                          rules={[
+                              { required: true, message: 'required error' },
+                              { type: 'string', message: 'type error' },
+                              { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                          ]}
+                      />
+                      <Form.Switch label="是否同意" field='agree'/>
+                      <Form.InputNumber field='price' label='价格' style={{width: 200}}/>
+                      <Form.Select label="姓名" field='name' style={{width: 200}}>
+                          <Form.Select.Option value="mike">mike</Form.Select.Option>
+                          <Form.Select.Option value="jane">jane</Form.Select.Option>
+                          <Form.Select.Option value="kate">kate</Form.Select.Option>
+                      </Form.Select>
+                      <Form.CheckboxGroup label="角色" field='role' direction='horizontal'>
+                          <Form.Checkbox value="admin">admin</Form.Checkbox>
+                          <Form.Checkbox value="user">user</Form.Checkbox>
+                          <Form.Checkbox value="guest">guest</Form.Checkbox>
+                          <Form.Checkbox value="root">root</Form.Checkbox>
+                      </Form.CheckboxGroup>
+                      <Form.RadioGroup field="性别">
+                          <Form.Radio value="1">man</Form.Radio>
+                          <Form.Radio value="2">woman</Form.Radio>
+                      </Form.RadioGroup>
+                </Form>
+            </>
+        );
+    }
+}
+```
+
+-   更复杂的布局
+    你还可以结合 Grid 提供的 Row、Col,来对表单进行你想要的排列
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Col, Row } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        labelPosition='top'
+        getFormApi={this.getFormApi}
+        style={{ padding: '10px' }}>
+        <Row>
+            <Col span={8}>
+                <Form.Input
+                    field="nickName1"
+                    label="用户名"
+                    style={{ width: '250px' }}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                    ]}
+                />
+            </Col>
+            <Col span={8}>
+                <Form.DatePicker field='date1' label='有效日期' style={{ width: '250px' }}/>
+            </Col>
+            <Col span={8}>
+                <Form.Select label="业务线" field='business1' style={{ width: '250px' }}>
+                    <Form.Select.Option value="tiktok">抖音</Form.Select.Option>
+                    <Form.Select.Option value="ulikeCam">轻颜相机</Form.Select.Option>
+                    <Form.Select.Option value="toutiao">今日头条</Form.Select.Option>
+                </Form.Select>
+            </Col>
+        </Row>
+        <Row>
+            <Col span={6}>
+                <Form.Input
+                    field="nickName2"
+                    label="用户名"
+                    style={{ width: '200px' }}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                    ]}
+                />
+            </Col>
+            <Col span={6}>
+                <Form.DatePicker field='date2' label='有效日期' style={{ width: '200px' }}/>
+            </Col>
+            <Col span={6}>
+                <Form.Select label="业务线" field='business2' style={{ width: '200px' }}>
+                    <Form.Select.Option value="tiktok">抖音</Form.Select.Option>
+                    <Form.Select.Option value="ulikeCam">轻颜相机</Form.Select.Option>
+                    <Form.Select.Option value="toutiao">今日头条</Form.Select.Option>
+                </Form.Select>
+            </Col>
+            <Col span={6}>
+                <Form.Select field="role" label='角色' style={{ width: '200px' }}>
+                    <Form.Select.Option value="operate">运营</Form.Select.Option>
+                    <Form.Select.Option value="rd">开发</Form.Select.Option>
+                    <Form.Select.Option value="pm">产品</Form.Select.Option>
+                    <Form.Select.Option value="ued">设计</Form.Select.Option>
+                </Form.Select>
+            </Col>
+        </Row>
+    </Form>
+)
+```
+
+### 表单分组
+
+字段数量较多的表单应考虑对字段进行分组,可以使用`Form.Section`对 Fields 进行分组(仅影响布局,不会影响数据结构)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+    
+() => {
+    const { Section, Input, DatePicker, TimePicker, Select, Switch, InputNumber, Checkbox, CheckboxGroup, RadioGroup } = Form;
+    return (
+        <Form style={{ width:560 }}>
+            <Section text={'基本信息'}>
+                <Input field='name' label='考试名称' initValue='TCS任务平台使用' style={{ width: 560 }}/>
+            </Section>
+            <Section text={'合格标准'} >
+                <div style={{display:'flex'}}>
+                   <InputNumber field='pass' initValue={60} style={{width:80}} label={{text:'及格正确率', required: true}}/>
+                   <InputNumber field='number' initValue={10} style={{width:80}} label={{text:'合格人数', required: true}}/>
+                </div>
+            </Section>
+            <Section text={'考试时间'} >
+               <DatePicker field='date' type='dateTime' initValue={new Date()} style={{width:272}} label={{text:'开始时间', required: true}}/>
+               <div  style={{display:'flex'}}>
+                 <Input field='time' label='考试时长' style={{ width: 176 }} initValue={'60'} addonAfter='分钟'/>
+                 <Checkbox initValue={true} noLabel field='auto' style={{paddingTop: 30, marginLeft: 12}}>到时间自动交卷</Checkbox>
+               </div>
+                <RadioGroup
+                    field="type"
+                    label='有效时间'
+                    direction='vertical'
+                    initValue={'always'}
+                >
+                    <Radio value="always">永久有效</Radio>
+                    <Radio value="user">自定义有效期</Radio>
+                </RadioGroup>
+                <RadioGroup
+                    field="type"
+                    label='答案放出时间'
+                    direction='vertical'
+                    initValue={'always'}
+                    rules={[
+                        { required: true }
+                    ]}
+                >
+                    <Radio value="always">自动放出</Radio>
+                    <Radio value="user">
+                      <div style={{display:'inline-block'}}>
+                      自定义放出时间
+                      <Form.DatePicker type='dateTimeRange' noLabel field='customTime' style={{width:464, display: 'inline-block'}}/>
+                      </div>
+                    </Radio>
+                </RadioGroup>
+            </Section>
+            <Section text={'考试人员'}>
+                <div style={{display: 'flex'}}>
+                    <Switch field='open'  label={{ text:'对外开放', required: true }} checkedText='开' uncheckedText='关'></Switch>
+                </div>
+                <Select
+                  field='users'
+                  label={{ text:'考生', required: true }}
+                  style={{width: 560}}
+                  multiple
+                  initValue={['1','2','3', '4']}
+                >
+                    <Select.Option value='1'>曲晨一</Select.Option>
+                    <Select.Option value='2'>夏可曼</Select.Option>
+                    <Select.Option value='3'>曲晨三</Select.Option>
+                    <Select.Option value='4'>蔡妍</Select.Option>
+                </Select>
+            </Section>
+            <Button type='primary' theme='solid' style={{ width: 120, marginTop: 12, marginRight: 4 }}>创建考试</Button>
+            <Button style={{marginTop: 12}}>预览</Button>
+        </Form>
+    )
+}
+```
+
+### wrapperCol / labelCol
+
+需要为 Form 内的所有 Field 设置统一的布局时,可以在 Form 上设置 wrapperCol 、labelCol 快速生成布局,无需手动使用 Row、Col 手动布局  
+`wrapperCol`、`labelCol`属性配置参考[Col 组件](/zh-CN/basic/grid#Col)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form
+        wrapperCol={{ span: 20 }}
+        labelCol={{ span: 2 }}
+        labelPosition='left'
+        labelAlign='right'
+    >
+        <Form.Input field='name' style={{width: 250}} label='姓名' trigger='blur' placeholder='请输入姓名'/>
+        <Form.Select field="role" label='角色' placeholder='请选择角色' style={{width: 250}}>
+            <Form.Select.Option value="operate">运营</Form.Select.Option>
+            <Form.Select.Option value="rd">开发</Form.Select.Option>
+            <Form.Select.Option value="pm">产品</Form.Select.Option>
+            <Form.Select.Option value="ued">设计</Form.Select.Option>
+        </Form.Select>
+    </Form>
+)
+```
+
+### 隐藏Label
+
+Form 会自动为 Field 控件插入 Label。如果你不需要自动插入 Label 模块, 可以通过在 Field 中设置`noLabel=true`将自动插入 Label 功能关闭
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form onSubmit={(values) => console.log(values)} style={{ width: 400 }}>
+        <Form.Input field='name' label='姓名' trigger='blur' noLabel={true} style={{width: 250}} placeholder='请输入姓名'/>
+        <Form.Select field="role" label='角色' style={{ width: '250px' }} noLabel={true} placeholder='请选择角色'>
+            <Form.Select.Option value="operate">运营</Form.Select.Option>
+            <Form.Select.Option value="rd">开发</Form.Select.Option>
+            <Form.Select.Option value="pm">产品</Form.Select.Option>
+            <Form.Select.Option value="ued">设计</Form.Select.Option>
+        </Form.Select>
+    </Form>
+)
+```
+
+### 导出 Label、ErrorMessage 使用
+
+如果你需要 Form.Label、Form.ErrorMessage 模块自行组合使用,可以从 Form 中导出
+
+-   Label 的 API 详见[Label](#Form.Label)
+-   ErrorMessage 的 API 详见[ErrorMessage](#Form.ErrorMessage)
+
+例如:当自带的 Label、ErrorMessage 布局不满足业务需求,需要自行组合位置,但又希望能直接使用 Label、ErrorMessage 的默认样式时
+
+```
+import { Form } from '@douyinfe/semi-ui';
+const { Label, ErrorMessage } = Form;
+```
+
+### 使用 Form.Slot 放置自定义组件
+
+当你的自定义组件,需要与 Field 组件保持同样的布局样式时,你可以通过 Form.Slot 放置你的自定义组件  
+在 Form 组件上设置的 labelWidth、labelAlign、wrapperCol、labelCol 会自动作用在 Form.Slot 上  
+Slot 属性配置详见[Form.Slot](#Form.Slot)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+class AssistComponent extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        return (
+            <Form
+                onChange={v=>console.log(v)}
+                onSubmit={v=>console.log(v)}
+                style={{width: 600}}
+                labelPosition='left'
+                labelWidth={100}
+            >
+                <Form.Input field='特效名称' style={{width: 250}}/>
+                <Form.Select
+                    style={{width: 250}}
+                    field="type"
+                    label="特效类型"
+                >
+                    <Form.Select.Option value="脸部贴纸">脸部贴纸</Form.Select.Option>
+                    <Form.Select.Option value="前景贴纸">前景贴纸</Form.Select.Option>
+                </Form.Select>
+                <Form.ErrorMessage />
+                <Form.Slot label={{ text: 'SlotA' }}>
+                    <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>
+                        我是Semi Form SlotA, 我是自定义的ReactNode
+                    </div>
+                </Form.Slot>
+                <Form.Slot label={{ text: 'SlotB', width: 160, align: 'right' }}>
+                    <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>
+                        我是Semi Form SlotB, 我的Label Align、Width与众不同
+                    </div>
+                </Form.Slot>
+            </Form>
+    )}
+}
+```
+
+### 内嵌 Label
+
+通过将 labelPositon 设为`inset`,可以将 Label 内嵌在表单控件中。目前支持这项功能的组件有`Input`、`InputNumber`、`DatePicker`、`TimePicker`、`Select`、`TreeSelect`、`Cascader`
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => (
+    <Form labelPosition='inset' layout='horizontal'>
+        <Form.Input field='name' label='姓名' trigger='blur' style={{width: 250}} placeholder='请输入姓名' initValue='semi'/>
+        <Form.Select field="role" label='角色' style={{ width: '250px' }} initValue='rd'>
+            <Form.Select.Option value="operate">运营</Form.Select.Option>
+            <Form.Select.Option value="rd">开发</Form.Select.Option>
+            <Form.Select.Option value="pm">产品</Form.Select.Option>
+            <Form.Select.Option value="ued">设计</Form.Select.Option>
+        </Form.Select>
+        <Form.DatePicker field="date" label='开始日期' style={{ width: '250px' }} initValue={new Date()}>
+        </Form.DatePicker>
+    </Form>
+)
+```
+
+### 使用 helpText、extraText 放置提示信息
+
+可以通过`helpText`放置自定义提示信息,与校验信息(error)公用同一区块展示,两者均有值时,优先展示校验信息。  
+可以通过`extraText`放置额外的提示信息,当需要错误信息和提示文案同时出现时,可以使用这个配置,常显,位于 helpText/error 后  
+当传入 validateStatus 时,优先展示 validateStatus 值对应的 UI 样式。不传入时,以 field 内部校验状态为准。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+class HelpAndExtra extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            helpText: '',
+            validateStatus: 'default'
+        }
+        this.formApi = null;
+        this.getFormApi = this.getFormApi.bind(this);
+        this.validate = this.validate.bind(this);
+        this.random = this.random.bind(this);
+    }
+
+    getFormApi(formApi) {
+        this.formApi = formApi;
+    }
+
+    validate(val, values) {
+        if (!val) {
+            this.setState({ validateStatus: 'error' })
+            return <span>密码不能为空</span>;
+        } else if (val && val.length <= 3) {
+            this.setState({
+                helpText: <span style={{ color: 'var(--semi-color-warning)' }}>'密码强度:弱'</span>,
+                validateStatus: 'warning'
+            }); // show helpText
+            return ''; // validate pass
+        } else {
+            this.setState({
+                helpText: '',
+                validateStatus: 'success'
+            });
+            return '';
+        }
+    }
+
+    random() {
+        let pw = (Math.random() * 100000).toString().slice(0, 5);
+        this.formApi.setValue('Password', pw);
+        this.formApi.setError('Password', '');
+        this.setState({ helpText: '', validateStatus: 'success' });
+    }
+
+    render() {
+        let { helpText, validateStatus } = this.state;
+        return (
+            <Form
+                getFormApi={this.getFormApi}
+                showValidateIcon={true}
+                onSubmit={(value) => console.log('submit success')}
+                onSubmitFail={(errors) => console.log(errors)}
+            >
+                <Form.Input
+                    validate={this.validate}
+                    field="Password"
+                    validateStatus={validateStatus}
+                    helpText={helpText}
+                    extraText={<div style={{
+                        color: 'rgba(var(--semi-blue-5), 1)',
+                        fontSize: 14,
+                        userSelect: 'none',
+                        cursor: 'pointer'
+                    }}
+                    onClick={this.random}>
+                        没有想到合适的密码?点击随机生成一个
+                    </div>}
+                ></Form.Input>
+            </Form>
+        );
+    }
+}
+```
+
+通过配置`extraTextPosition`,你可以控制extraText的显示位置。可选值 `bottom`、`middle`  
+例如如当你希望将extraText 提示信息显示在Label与Field控件中间时  
+该属性可在Form上统一配置,亦可在每个Field上单独配置,同时传入时,以Field的配置为准。  
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form } from '@douyinfe/semi-ui';
+
+() => {
+  const options = [
+    { label: '飞书通知', value: 'lark' },
+    { label: '邮件通知', value: 'email' },
+    { label: '顶部横幅通知', value: 'notification' }
+  ];
+  const notifyText = '未勾选时,默认为红点提醒,消息默认进入收件人消息列表。对于重要通知,可同时勾选相应的通知方式。';
+  const forceText = '对于对话框通知,可指定该消息必须在指定时长后才可置为已读。';
+  return (
+    <Form extraTextPosition='middle'>
+      <Form.CheckboxGroup
+        direction='horizontal'
+        field='notify'
+        label='通知方式'
+        extraText={notifyText}
+        options={options}
+      />
+      <Form.InputNumber field='force' label='强制读取(可选)' placeholder='秒' extraText={forceText} extraTextPosition='bottom'/>
+    </Form>
+  );
+}
+
+```
+
+
+
+### 使用 InputGroup 组合多个 Field
+
+当你需要将一些表单控件组合起来使用时,你可以用`Form.InputGroup`将其包裹起来  
+当你给`Select`、`Input`等表单控件加上 field 属性时,`Form`会默认给每个 Field 控件自动插入`Label`  
+而在`InputGroup`中一般仅需要一个属于整个 Group 的 Label,你可以在 InputGroup 中设置 label 属性,插入一个属于 Group 的`Label`  
+`label`可配置属性详见[Label](#Form.Label)  
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Form onSubmit={(values) => console.log(values)} labelPosition='top' style={{ width: 400 }}>
+        <Form.InputGroup label={{ text: (<span>手机号码</span>), required: true }} labelPosition='top'>
+            <Form.Select style={{ width: 150 }} field='phonePrefix' initValue='+86' rules={[{ required: true }]} showClear>
+                <Form.Select.Option value='+1'>美国+1</Form.Select.Option>
+                <Form.Select.Option value='+852'>香港+852</Form.Select.Option>
+                <Form.Select.Option value='+86'>中国+86</Form.Select.Option>
+                <Form.Select.Option value='+81'>日本+81</Form.Select.Option>
+            </Form.Select>
+            <Form.Input initValue='18912345678' style={{ width: 250 }} field='phoneNumber' rules={[{ required: true }]} showClear />
+        </Form.InputGroup>
+        <Form.Input field='姓名' trigger='blur' initValue='Semi'></Form.Input>
+        <Button htmlType='submit'>提交</Button>
+    </Form>
+)
+```
+
+### Modal 弹出层中的表单
+
+你可以将 Form 放置于 Modal 中,以弹窗形式承载  
+在提交时,通过 formApi.validate()对 Field 进行集中校验
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Modal, Button, Row, Col } from '@douyinfe/semi-ui';
+
+class ModalFormDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            visible: false,
+        }
+        this.showDialog = this.showDialog.bind(this);
+        this.handleOk = this.handleOk.bind(this);
+        this.handleCancel = this.handleCancel.bind(this);
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    showDialog() {
+        this.setState({ visible: true });
+    }
+
+    handleOk() {
+        this.formApi.validate()
+            .then((values) => {
+                console.log(values)
+            })
+            .catch((errors) => {
+                console.log(errors)
+            });
+    }
+
+    handleCancel() {
+        this.setState({ visible: false })
+    }
+
+    getFormApi(formApi) {
+        this.formApi = formApi;
+    }
+
+    render(){
+        const {visible} = this.state;
+        let message = '该项为必填项';
+        return (
+            <>
+                <Button onClick={this.showDialog}>打开弹窗</Button>
+                <Modal
+                    title="新建"
+                    visible={visible}
+                    onOk={this.handleOk}
+                    style={{width: 600}}
+                    onCancel={this.handleCancel}
+                >
+                    <Form
+                        getFormApi={this.getFormApi}
+                    >
+                        <Row>
+                            <Col span={5}>
+                                <Form.Select
+                                    field='region'
+                                    label="国家/地区"
+                                    placeholder='请选择'
+                                    style={{width:'100%'}}
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                >
+                                    <Form.Select.Option value="China">中国</Form.Select.Option>
+                                    <Form.Select.Option value="US">美国</Form.Select.Option>
+                                    <Form.Select.Option value="Europe">欧洲</Form.Select.Option>
+                                    <Form.Select.Option value="Japan">日本</Form.Select.Option>
+                                </Form.Select>
+                            </Col>
+                            <Col span={15} offset={2}>
+                                <Form.Input
+                                    field='owner'
+                                    label="业务执行人"
+                                    trigger='blur'
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                />
+                            </Col>
+                        </Row>
+                        <Row>
+                            <Col span={5}>
+                                <Form.Select
+                                    field='area'
+                                    label="投放区域"
+                                    placeholder='请选择'
+                                    style={{width:'100%'}}
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                >
+                                    <Form.Select.Option value="China">中国</Form.Select.Option>
+                                    <Form.Select.Option value="US">美国</Form.Select.Option>
+                                    <Form.Select.Option value="Europe">欧洲</Form.Select.Option>
+                                    <Form.Select.Option value="Japan">日本</Form.Select.Option>
+                                </Form.Select>
+                            </Col>
+                            <Col span={15} offset={2}>
+                                <Form.Input
+                                    field='department'
+                                    label="业务执行部门"
+                                    trigger='blur'
+                                    rules={[
+                                        { required: true, message },
+                                    ]}
+                                />
+                            </Col>
+                        </Row>
+                    </Form>
+                </Modal>
+            </>
+        );
+    }
+}
+```
+
+### 配置初始值与校验规则
+
+-   你可以通过`rules`为每个 Field 表单控件配置校验规则  
+    Form 内部的校验库基于 async-validator,更多配置规则可查阅其[官方文档](https://github.com/yiminghe/async-validator)
+-   你可以通过 form 的`initValues`为整个表单统一设置初始值,也可以在每个 field 中通过`initValue`设置初始值(后者优先级更高)
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class BasicDemoWithInit extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            initValues: {
+                name: 'semi',
+                role: 'rd'
+            }
+        };
+        this.getFormApi = this.getFormApi.bind(this);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi }
+
+    render() {
+        const { Select, Input } = Form;
+        const style = { width: '100%' }
+        return (
+            <Form initValues={this.state.initValues}>
+                <Input
+                    field="name"
+                    label="名称(Input)"
+                    style={style}
+                    trigger='blur'
+                    rules={[
+                        { required: true, message: 'required error' },
+                        { type: 'string', message: 'type error' },
+                        { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                    ]}
+                />
+                <Select field="role" style={style} label='角色' placeholder='请选择你的角色' initValue={'pm'}>
+                    <Select.Option value="operate">运营</Select.Option>
+                    <Select.Option value="rd">开发</Select.Option>
+                    <Select.Option value="pm">产品</Select.Option>
+                    <Select.Option value="ued">设计</Select.Option>
+                </Select>
+                <Button htmlType='submit'>提交</Button>
+            </Form>
+        )
+    }
+}
+```
+
+### 自定义校验(Form 级别)
+
+你可以给`Form`整体设置自定义校验函数 validateFields,submit 或调用formApi.validate()时会进行调用
+
+#### 同步校验
+
+校验通过时,你应该返回一个空字符串;  
+校验失败时,你应该返回错误信息(Object,key 为 fieldName,value 为对应的错误信息)
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FormLevelValidateSync extends React.Component {
+    constructor() {
+        super();
+        this.syncValidate = this.syncValidate.bind(this);
+    }
+
+    syncValidate(values) {
+        const errors = {};
+        if (values.name !== 'mike') {
+            errors.name = 'you must name mike';
+        }
+        if (values.sex !== 'female') {
+            errors.sex = 'must be woman';
+        }
+        errors.familyName = [
+            { before: 'before errror balabala ', after: 'after error balabala' },
+            'familyName[1] error balabala'
+        ];
+        return errors;
+    }
+
+    render() {
+        return (
+            <Form validateFields={this.syncValidate} layout='horizontal'>
+                <Form.Input field='name' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].before' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].after' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[1]' trigger='blur'></Form.Input>
+                <div style={{display: 'flex', alignItems: 'flex-end'}}>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </div>
+            </Form >
+        );
+    }
+}
+```
+
+#### 异步校验
+
+异步校验时,你应当返回一个 promise,在 promise.then()中 你需要 return 对应的错误信息
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FormLevelValidateAsync extends React.Component {
+    constructor() {
+        super();
+        this.asyncValidate = this.asyncValidate.bind(this);
+    }
+
+    asyncValidate(values) {
+        const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
+        return sleep(2000).then(() => {
+            let errors = {};
+            if (values.name !== 'mike') {
+                errors.name = 'you must name mike';
+            }
+            if (values.sex !== 'female') {
+                errors.sex = 'sex not valid';
+            }
+            return errors;
+        });
+    }
+
+    render() {
+        return (
+            <Form validateFields={this.asyncValidate} layout='horizontal'>
+                <Form.Input field='name' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[0].before' trigger='blur'></Form.Input>
+                <Form.Input field='familyName[1]' trigger='blur'></Form.Input>
+                <Form.Input field='sex' trigger='blur'></Form.Input>
+                <div style={{display: 'flex', alignItems: 'flex-end'}}>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </div>
+            </Form >
+        );
+    }
+}
+```
+
+### 自定义校验(Field 级别)
+
+你可以指定单个表单控件的自定义校验函数,支持同步、异步校验(通过返回 promise)
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+class FieldLevelValidateDemo extends React.Component {
+    constructor() {
+        super();
+        this.validateName = this.validateName.bind(this);
+        this.asyncValidate = this.asyncValidate.bind(this);
+    }
+
+    validateName(val) {
+        if (!val) {
+             return '【sync】can\'t be empty';
+        } else if (val.length <= 5) {
+            return '【sync】must more than 5';
+        }
+        return '';
+    }
+
+    asyncValidate(val, values) {
+        const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
+        return sleep(2000).then(() => {
+            if (!val) {
+                return '【async】can\'t be empty';
+            } else if (val.length <= 5) {
+                return '【async】must more than 5';
+            } else {
+                return '';
+            }
+        });
+    }
+
+    render() {
+        return (
+            <Form>
+                <Form.Input field='name' label='【name】asyncValidate after 2s' validate={this.asyncValidate} trigger='blur'></Form.Input>
+                <Form.Input field='familyName' label='【familyName】syncValidate' validate={this.validateName} trigger='blur'></Form.Input>
+                <Button htmlType="reset">reset</Button>
+            </Form >
+        );
+    }
+}
+```
+
+
+### 表单联动
+
+你可以通过监听 Field 的 onChange 事件,然后使用 formApi 进行相关修改,来使 Field 之间达到联动
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { Form, Button, Row } from '@douyinfe/semi-ui';
+
+class LinkFieldForm extends React.Component {
+    constructor() {
+        super();
+        this.getFormApi = this.getFormApi.bind(this);
+        this.handleSelectChange = this.handleSelectChange.bind(this);
+    }
+
+    handleSelectChange(value) {
+        let text = value === 'male' ? 'Hi male' : 'Hi female!';
+        this.formApi.setValue('Note', text);
+    }
+
+    getFormApi(formApi) { this.formApi = formApi; }
+
+    render() {
+        return (
+            <Form getFormApi={this.getFormApi} onValueChange={values => console.log(values) } style={{ width: 250 }}>
+                <span>Note will change after Sex select</span>
+                <Form.Input field="Note" style={{ width: 250 }}/>
+                <Form.Select field="Sex" onChange={this.handleSelectChange} style={{ width: 250 }}>
+                    <Form.Select.Option value="female">female</Form.Select.Option>
+                    <Form.Select.Option value="male">male</Form.Select.Option>
+                </Form.Select>
+                <Row>
+                    <Button type="primary" htmlType="submit" className="btn-margin-right">
+                        Submit
+                    </Button>
+                    <Button htmlType="reset">reset</Button>
+                </Row>
+            </Form>
+        );
+    }
+}
+```
+
+### 动态表单
+
+#### 动态删减表单项
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Form, Button } from '@douyinfe/semi-ui';
+
+() => (
+    <Form style={{ width: 450 }}>
+        {({ formState }) => (
+            <React.Fragment>
+                <Form.Input field="name" label='用户名称:' />
+                <Form.RadioGroup field="isAnchor" label='是否已注册主播'>
+                    <Form.Radio value="yes">yes</Form.Radio>
+                    <Form.Radio value="no">no</Form.Radio>
+                </Form.RadioGroup>
+                {formState.values.isAnchor === 'yes' ? (
+                    <Form.Input field="liveRoom" label='直播间名称' />
+                ) : null}
+                <Button htmlType="submit">提交</Button>
+            </React.Fragment>
+        )}
+    </Form>
+)
+```
+
+#### 数组类动态增删表单项-使用 ArrayField
+
+针对动态增删的数组类表单项,我们提供了 ArrayField 作用域来简化 add/remove 的操作  
+ArrayField 自带了 add、remove、addWithInitValue 等 api 用来执行新增行,删除行,新增带有初始值的行等操作  
+注意:ArrayField 的 initValue 类型必须是数组
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { ArrayField, TextArea, Form, Button, useFormState } from '@douyinfe/semi-ui';
+
+class ArrayFieldDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            menu: [
+                { name: '脸部贴纸', type: '2D' },
+                { name: '前景贴纸', type: '3D' },
+            ]
+        }
+    }
+
+    render() {
+        let { menu } = this.state;
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <TextArea style={{marginTop: 10}} value={JSON.stringify(formState)} />
+            );
+        };
+        return (
+            <Form style={{ width: 500 }} labelPosition='left' labelWidth='220px' allowEmpty>
+                <ArrayField field='effects' initValue={menu}>
+                    {({ add, arrayFields, addWithInitValue }) => (
+                        <React.Fragment>
+                            <Button onClick={add} icon={<IconPlusCircle />} theme='light'>新增空白行</Button>
+                            <Button  icon={<IconPlusCircle />} onClick={() => {addWithInitValue({name: '自定义贴纸', type: '2D'})}} style={{marginLeft:8}}>新增带有初始值的行</Button>
+                            {
+                                arrayFields.map(({ field, key, remove }, i) => (
+                                    <div key={key} style={{ width: 1000, display: 'flex' }}>
+                                        <Form.Input
+                                            field={`${field}[name]`}
+                                            label={`特效类型:(${field}.name)`}
+                                            style={{width: 200, marginRight: 16}}
+                                        >
+                                        </Form.Input>
+                                        <Form.Select
+                                            field={`${field}[type]`}
+                                            label={`素材类型:(${field}.type)`}
+                                            style={{width: 90}}
+                                        >
+                                            <Form.Select.Option value='2D'>2D</Form.Select.Option>
+                                            <Form.Select.Option value='3D'>3D</Form.Select.Option>
+                                        </Form.Select>
+                                        <Button type='danger' theme='borderless' icon={<IconMinusCircle />} onClick={remove} style={{ margin: 12 }}></Button>
+                                    </div>
+                                ))
+                            }
+                        </React.Fragment>
+                    )}
+                </ArrayField>
+                <ComponentUsingFormState />
+            </Form>
+        );
+    }
+}
+```
+
+### Hooks 的使用
+
+我们提供了四个 Hooks,使你在不需要通过 props 传递的情况下,也能在放置于 Form 结构内部的 Functional Component 中也能轻易访问到 Form 内部状态数据,以及调用 Form、Field 的相关 api
+
+```jsx
+import { useFormApi, useFormState, useFieldApi, useFieldState } from '@douyinfe/semi-ui';
+```
+
+#### useFormApi
+
+useFormApi 允许你通过 hook,在 Functional Component 内直接访问父级 Form 组件的 formApi
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { useFormApi, Form, Button } from '@douyinfe/semi-ui';
+
+class UseFromApiDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFormApi = () => {
+            const formApi = useFormApi();
+            const change = () => {
+                formApi.setValue('name', Math.random());
+            };
+            return (
+                <Button onClick={change}>ChangeName By【formApi】</Button>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <ComponentUsingFormApi />
+            </Form>
+        )
+    }
+}
+```
+
+#### useFormState
+
+useFormState 允许你通过 hook,在 Functional Component 内直接访问父级 Form 组件的 formState
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { useFormState, Form } from '@douyinfe/semi-ui';
+
+class UseFromStateDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <pre>
+                    <code>{JSON.stringify(formState)}</code>
+                </pre>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <h5>FormState read by 【useFormState】:</h5>
+                <ComponentUsingFormState />
+            </Form>
+        );
+  }
+}
+```
+
+#### useFieldApi
+
+useFieldApi 允许你通过 hook,在 Functional Component 内直接调用指定 Field 的 api
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { useFieldApi, Form, Button } from '@douyinfe/semi-ui';
+
+class UseFieldApiDemo extends React.Component {
+    constructor() { super(); }
+    render() {
+        const ComponentUsingFieldApi = () => {
+            const nameFieldApi = useFieldApi('name');
+            const change = () => {
+                nameFieldApi.setValue(Math.random());
+            };
+            return (
+                <Button onClick={change}>Click Me!!! changeNameBy【fieldApi】</Button>
+            );
+        };
+        return (
+            <Form>
+                <Form.Input field='name' initValue='mike'></Form.Input>
+                <ComponentUsingFieldApi />
+            </Form>
+        )
+    }
+}
+```
+
+#### useFieldState
+
+useFieldState 允许你通过 hook,在 Functional Component 内直接访问指定 Field 的 State
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { useFieldState, Form } from '@douyinfe/semi-ui';
+
+class UseFieldStateDemo extends React.Component {
+  constructor() {
+    super();
+  }
+  render() {
+    const ComponentUsingFieldState = props => {
+        const fieldState = useFieldState(props.field);
+        return (
+            <>
+              <span>【{props.field}】FieldState read by 【useFieldState】:</span>
+              <code>{JSON.stringify(fieldState)}</code>
+            </>
+        );
+    };
+    return (
+       <Form>
+            <Form.Input field='name' initValue='mike'></Form.Input>
+            <ComponentUsingFieldState field='name' />
+            <Form.Input field='country' initValue='china'></Form.Input>
+            <ComponentUsingFieldState field='country' />
+      </Form>
+    )
+  }
+}
+```
+
+### HOC 的使用
+
+我们提供了两个 HOC: `withFormApi`、`withFormState`,可以在其他组件内部访问到 Form 的 api 以及内部状态  
+提供了 HOC: `withField`,用于将自定义组件封装成符合 Semi Form 数据流的表单控件
+
+```
+import { withFormApi, withFormState, withField } from '@douyinfe/semi-ui';
+```
+
+#### HOC-withFormApi
+
+你可以通过 withFormApi HOC 来封装组件,使得该组件内部可以直接调用父级 Form 组件的 formApi  
+注意封装后的组件必须放置于 Form 结构内部
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { withFormApi, Form, Button } from '@douyinfe/semi-ui';
+
+class withFormApiDemo extends React.Component {
+    constructor() {
+        super();
+    }
+    renderComponentWithFormApi() {
+        const SomeComponetInsideForm = props => (
+            <Button onClick={() => {
+                props.formApi.setValue('name', Math.random());
+            }}>Click Me!!! ChangeName By【formApi】</Button>
+        );
+        return ComponentWithFormApi = withFormApi(SomeComponetInsideForm);
+
+    }
+    render() {
+        const ComponentWithFormApi = this.renderComponentWithFormApi();
+        return (
+            <Form>
+                <Form.Input field='name' initValue='steve'></Form.Input>
+                <Form.Input field='familyName' initValue='jobs'></Form.Input>
+                <Button htmlType='submit' style={{ marginRight: 4 }}>submit</Button>
+                <ComponentWithFormApi />
+            </Form>
+        );
+    }
+}
+```
+
+#### HOC-withFormState
+
+你可以通过 withFormState HOC 来封装组件,使得该组件内部可直接访问到父级 Form 组件的 FormState  
+注意封装后的组件必须放置于 Form 结构内部
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { withFormState, Form } from '@douyinfe/semi-ui';
+
+class withFormStateDemo extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        const SomeComponentInsideForm = props => (
+            <code>{JSON.stringify(props.formState)}</code>
+        );
+        const ComponentWithFormState = withFormState(SomeComponentInsideForm);
+
+        return (
+            <Form>
+                <Form.Input field='name' initValue='steve'></Form.Input>
+                <Form.Input field='familyName' initValue='jobs'></Form.Input>
+                <ComponentWithFormState />
+            </Form>
+        );
+    }
+}
+```
+
+### withField 封装自定义表单控件
+
+通过 withField,你可以将其他自定义组件扩展成为表单控件,由 Form 接管其行为
+
+注意:自定义组件必须为受控组件
+
+withField 主要做了以下事情
+
+-   负责接管组件的 value(或者 valueKey 指定的其他属性)、onChange(或 onKeyChangeFnName 指定的其他回调函数)
+-   负责在表单控件上方插入 Field 的`<Form.Label>`
+-   负责在表单控件下方插入 Field 的`<ErrorMessage>`
+-   负责在表单控件下方插入 Field 的 extraText
+
+withFieldOptions 具体配置可参考[withField Option](#withFieldOptions)
+
+你的自定义受控组件需要做以下事情:  
+值发生变化时,调用props.onChange并且将最新的值作为入参  
+响应props.value的变化,并更新你的组件UI渲染结果  
+
+```jsx
+withField(YourComponent, withFieldOptions);
+```
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { withField, Form } from '@douyinfe/semi-ui';
+
+class withFieldDemo1 extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        // 这里将html原生的input封装
+        const htmlInput = (props) => {
+            let value = props.value || '';
+            let { validateStatus, ...rest } = props; // prevent props being transparently transmitted to DOM
+            return <input {...rest} value={value} />; 
+        };
+        const CustomInput = withField(htmlInput, { valueKey: 'value', onKeyChangeFnName: 'onChange', valuePath: 'target.value' });
+        // 观察formState,看input的数据流是否已被form接管
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <pre>
+                    <code>{JSON.stringify(formState)}</code>
+                </pre>
+            );
+        };
+        return (
+            <Form>
+                <CustomInput field='name' />
+                <ComponentUsingFormState />
+            </Form>
+        );
+    }
+}
+```
+
+```jsx live=true dir="column" hideInDSM
+import React from 'react';
+import { withField, Input, Select, Form } from '@douyinfe/semi-ui';
+
+class withFieldDemo2 extends React.Component {
+    constructor() {
+        super();
+    }
+    render() {
+        // 此处纯粹是为了在同一个playground中演示,将组件的声明放在了render函数中。
+        // 实际业务上,建议将组件声明以及withField封装抽离至外部,作为单独组件声明
+        const MyComponent = (props) => {
+            const { onChange, value } = props;
+            const { name, role } = value || {};
+            const handleChange = (v, type) => {
+                let newValue = { ...value, [type==='name' ? 'name' : 'role']: v };
+                onChange(newValue);
+            };
+            return (
+                <div className='customField'>
+                    <Input insetLabel='名称' value={name} onChange={v => handleChange(v, 'name')} style={{ width: 180, marginRight:12 }} />
+                    <Select
+                        insetLabel='角色'
+                        value={role}
+                        onChange={v => handleChange(v, 'role')}
+                        style={{ width: 200 }}
+                        optionList={[{ value: 'rd', label: '开发' }, { value: 'UED', label: '设计师' }]}
+                    />
+                </div>
+            );
+        }
+        const CustomField = withField(MyComponent, { valueKey: 'value', onKeyChangeFnName: 'onChange' });
+
+        const ComponentUsingFormState = () => {
+            const formState = useFormState();
+            return (
+                <pre>
+                    <code>{JSON.stringify(formState)}</code>
+                </pre>
+            );
+        };
+
+        return (
+            <Form>
+                <CustomField field='baseInfo' label={{ text:'基本信息', required: true }} />
+                <ComponentUsingFormState />
+            </Form>
+        );
+    }
+}
+```
+
+## API 参考
+
+## Form Props
+
+| 属性              | 说明                                                                                                                                                                         | 类型                                          | 默认值     |
+| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ---------- |
+| autoScrollToError | 若为 true,submit 或者调用 formApi.validate()校验失败时,将会自动滚动至出错的字段。object 型配置参考[options](https://github.com/stipsan/scroll-into-view-if-needed#options) <br/>**在 v0.33.0 开始提供** | boolean\| object                              | false      |
+| className         | form 标签的 classname                                                                                                                                                        | string                                        |
+| getFormApi        | form mounted 时会回调该函数,将 formAPI 作为参数传入。formApi 可用于修改 form 内部状态(值、校验状态、错误信息)                                                             | function(formApi:object)                      |            |
+| initValues        | 用于统一设置表单初始值(仅会在组件挂载时消费一次),例如{fieldA:'hello', fieldB:['arr1', 'arr2']}                                                                       | object                                        |            |
+| onChange          | form 更新时触发,包括表单控件挂载/卸载/值变更/blur/验证状态变更/错误提示变更, 入参为 formState                                                                               | function(formState:object)                    |            |
+| onValueChange     | form 的值被更新时触发,仅在表单控件值发生变化时触发。第一个入参为 formState.values,第二个入参为当前发生变化的 field                                                         | function(values:object, changedValue: object) |            |
+| onReset           | 点击 reset 按钮或调用 `formApi.reset()`时的回调函数                                                                                                                          | function()                                    |            |
+| onSubmit          | 点击 submit 按钮或调用 `formApi.submitForm()`,数据验证成功后的回调函数                                                                                                      | function(values:object)                       |            |
+| onSubmitFail      | 点击 submit 按钮或调用 `formApi.submitForm()`,数据验证失败后的回调函数                                                                                                      | function(errors:object, values:object)        |            |
+| validateFields    | Form 级别的自定义校验函数,submit 时或 formApi.validate 时会被调用(配置Form级别校验器后,Field级别校验器在submit或formApi.validate()时不会再被触发)。支持同步校验、异步校验                                                                                   | function(values)                              |            |
+| component         | 用于声明表单控件,不可与 render、props.children 同时使用                                                                                                                     | ReactNode                                     |            |
+| render            | 用于声明表单控件,不可与 component、props.children 同时使用                                                                                                                  | function                                      |
+| allowEmpty        | 是否保留values中为空值的field的key,true时保留key,false时移除key                                     | boolean                                       | false      |
+| layout            | Form 表单控件间的布局,目前支持水平(horizontal)、垂直(vertical)两种                                                                                                          | string                                        | 'vertical' |
+| labelPosition     | 统一配置Field 中 label 的位置,可选'top'、'left'、'inset'(inset 标签内嵌仅部分组件支持)                                                                                              | string                                        | 'top'      |
+| labelWidth        | 统一配置label 宽度                                                                                                                                                                   | string\|number                                |            |
+| labelAlign        | 统一配置label 的 text-align 值                                                                                                                                                       | string                                        | 'left'     |
+| style             | 可将内联样式传入 form 标签                                                                                                                                                   | object                                        |
+| wrapperCol        | 统一应用在每个 Field 上的布局,同[Col 组件](/zh-CN/basic/grid#Col),设置`span`、`offset`值,如{span: 20, offset: 4}                                 | object                                        |
+| labelCol          | 统一应用在每个 Field 的 label 标签布局,同[Col 组件](/zh-CN/basic/grid#Col),设置`span`、`offset`值,如{span: 6, offset: 2}                         | object                                        |
+| disabled          | 统一应用在每个 Field 的 disabled 属性 <br/>**在 v0.35.0 开始提供**                                                                                                             | boolean                                       | false      |
+| showValidateIcon  | Field 内的校验信息区块否自动添加对应状态的 icon 展示 <br/>**在 v1.0.0 开始提供**                                                                                                                         | boolean                                       | true       |
+| extraTextPosition  | 统一应用在每个 Field 上的extraTextPosition属性,控制extraText的显示位置,可选`middle`(垂直方向以Label、extraText、Field主体的顺序显示)、`bottom` (垂直方向以Label、Field主体、extraText的顺序显示)  <br/>**在 v1.9.0 开始提供**                                                                                                                       | string                                       | 'bottom'       |
+
+## FormState
+
+FormState 存储了所有 Form 内部的状态值,包括各表单控件的值,错误信息、touched 状态  
+进行表单提交时,实际提交的就是 formState.values
+
+| Name    | 说明                                                                | 初始值 | 示例                            |
+| ------- | ------------------------------------------------------------------- | ------ | ------------------------------- |
+| values  | 表单的值                                                            | {}     | { fieldA: 'str', fieldB: true } |
+| errors  | 表单错误信息集合,你可以通过判断是否有错误信息来决定是否允许用户提交 | {}     | { fieldA: 'length not valid'}   |
+| touched | 用户点击过的 field 集合                                             | {}     | { fieldA: true }                |
+
+### 如何访问 formState
+
+-   通过调用 formApi.getFormState()
+-   通过[child render function 方式声明表单](#支持的其他写法),formState 会作为参数注入
+-   通过[render props 方式声明表单](#支持的其他写法),formState 会作为参数注入
+-   通过[useFormState](#useFormState) hook
+-   通过[withFormState](#HOC-withFormState) HOC
+
+## FormApi
+
+我们提供了 FormApi。你在 Form 内部、外部都可以很方便地获取到 formApi,它允许你使用 getter 和 setter 来获取和操作 formState 的值。  
+下面的表格描述了 formApi 中可用的功能。
+
+| Function      | 说明                                                                                                                                                                                                                             | example                                                                                                                       |
+| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| getFormState  | 获取 FormState                                                                                                                                                                                                                   | formApi.getFormState()                                                                                                        |
+| submitForm    | 可手动触发 submit 提交操作                                                                                                                                                                                                       | formApi.submitForm()                                                                                                          |
+| reset         | 可手动对 form 进行重置                                                                                                                                                                                                           | formApi.reset()                                                                                                               |
+| validate      | 可手动触发对表单的校验,不传参时默认触发整全体Field的校验(配置Form级别校验器后,Field级别校验器在submit或formApi.validate()时不会再被触发),若想触发部分field的校验,将目标field数组传入即可                                                                                                                                                                                                       | formApi.validate()<br/>.then(values=>{})<br/>.catch(errors=>{}) <br/>或 formApi.validate(\['fieldA','fieldB'\])<br/>                                                              |
+| setValues     | 设置整个表单的值。第二个参数中的 isOverride 默认为 false<br/>默认情况下只会从`newValues`中取 Form 中已存在的 field 的值更新到`formState.values`中。<br/>当 isOverride 为`true`时,会直接以 newValues 覆盖赋值给 formState.values | formApi.setValues(newValues: object, { isOverride: boolean })                                                                 |
+| setValue      | 提供直接修改 formState.values 方法,与 setValues 的区别是它仅修改单个 field                                                                                                                                                      | formApi.setValue(field: string, newFieldValue: any)                                                                           |
+| getValue      | 获取 单个 Field 的值                                                                                                                                                                                                             | formApi.getValue() <br/>formApi.getValue(field: string)                                                                        |
+| getValues     | 获取 所有 Field 的值 <br/>**在 v0.35.0 开始提供                                                                                                                                                                                                            | formApi.getValues()                                                                                                           |
+| setTouched    | 修改 formState.touched                                                                                                                                                                                                           | formApi.setTouched(field: string, isTouched: boolean) <br/>                                                                   |
+| getTouched    | 获取 Field 的 touched 状态                                                                                                                                                                                                       | formApi.getTouched(field: string)                                                                                             |
+| setError      | 修改 某个 field 的 error 信息                                                                                                                                                                                                    | formApi.setError(field: string, fieldErrorMessage: string)                                                                    |
+| getError      | 获取 Field 的 error 状态                                                                                                                                                                                                         | formApi.getError(field: string)                                                                                               |
+| getFieldExist | 获取 Form 中是否存在对应的 field                                                                                                                                                                                                 | formApi.getFieldExist(field: string)                                                                                          |
+| scrollToField | 滚动至指定的 field <br/>**在 v0.33.0 开始提供**                                                                                                                                                                                                                   | formApi.scrollToField(field: string, scrollOpts: object |
+### 如何获取 formApi
+
+-   Form 组件在 ComponentDidMount 阶段,会执行 props 传入的 getFormApi 回调,你可以在回调函数中保存 formApi 的引用,以便后续进行调用(**示例如下代码**)  
+     除此之外,我们还提供了其他方式获取 formApi,你可以根据喜好选择不同的调用方式
+-   通过ref的方式获取Form组件实例,直接访问实例上的formApi
+-   通过[child render function 方式声明表单](#支持的其他写法),formApi 会作为参数注入
+-   通过[render props 方式声明表单](#支持的其他写法),formApi 会作为参数注入
+-   通过[useFormApi](#useFormApi) hook
+-   通过[withFormApi](#HOC-withFormApi) HOC
+
+```jsx
+class FormApiDemo extends React.Component {
+    constructor() {
+        super();
+        this.getFormApi = this.getFormApi.bind(this);
+        this.formBRef = React.createRef();
+    }
+
+    getFormApi(formApi) {
+        this.formApi = formApi;
+        // 获取到formApi对象后,你可以使用它来对表单进行任何你想做的修改 ~
+    }
+
+    changeValues() {
+        // 使用 FormA的 formApi
+        this.formApi.setValues({ a: 1});
+        // 使用 FormB的 formApi
+        this.formBRef.current.formApi.setValues({ b: 2});
+    }
+
+    render() {
+        return <>
+            // 通过getFormApi回调获取并保存formApi
+            <Form getFormApi={this.getFormApi} />
+            // 通过ref直接获取Form组件实例上的formApi
+            <Form ref={this.formBRef} />
+            <Button onClick={()=>this.changeValues()}>Change</Button>
+        </>
+    }
+}
+```
+
+```jsx
+() => {
+    // 函数式组件通过useRef存储formApi
+    const api = useRef();
+
+    return (<Form getFormApi={formApi => api.current = formApi}>
+        <Form.Input field='a' />
+        <Button onClick={()=>{console.log(api)}}>log</Button>
+    </Form>)
+}
+```
+
+## Field Props
+
+<Notice type="primary" title="关于Field ref">
+    v1.30.0之前的版本,Field组件并不会做ref转发<br/>
+    v1.30后可直接通过ref获取底层控件实例,例如给Form.Input、Form.Select指定ref,直接获取到底层原始Input、Select组件的ref引用
+</Notice>
+
+| 属性                  | 说明                                                                                                                                                                                                                | 类型                                                                                          | 默认值    |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------- |
+| field                 | 该表单控件的值在 formState.values 中的映射路径,Form 会使用该值来区分内部的表单控件<br/>**必填!!!** 示例:[Bindding Syntax](#表单控件值的绑定)                                                                      | string                                                                                        |           |
+| label                 | 该表单控件的 label 标签文本,不传的时候默认与 field 同名, 传入 object 时会将其透传给 Form.Label,具体配置请参考[Label](#Form.Label)                                                                                 | string\|object                                                                                |
+| labelPosition         | 该表单控件的 label 位置,可选'top'/'left'/'inset'。在Form与Field上同时传入时,以Field props为准 <br/>**v0.27.0 开始提供**                                                                                                                                         | string                                                                                        |
+| labelAlign            | 该表单控件的 label 文本的 text-align。在Form与Field上同时传入时,以Field props为准<br/>**v0.27.0 开始提供**                                                                                                                                                      | string                                                                                        |
+| labelWidth            | 该表单控件的 label 文本的 width。在Form与Field上同时传入时,以Field props为准 <br/>**v0.27.0 开始提供**                                                                                                                                                           | string\|number                                                                                |
+| noLabel               | 当你不需要自动添加 label 时,可以将该值置为 true                                                                                                                                                                    | boolean                                                                                       |
+| noErrorMessage        | 当你不需要自动添加 ErrorMessage 模块时,可以将该值置为 true,注意此时 helpText 也不会被展示                                                                                                                         | boolean                                                                                       |
+| name                  | 控件名称,传入时会自动在对应 field 的 div 中追加对应的 className,如:money => '.semi-form-field-money'                                                                                                             | string                                                                                        |
+| fieldClassName        | 整个 fieldWrapper 的 className,作用与 name 参数一致,区别是不会自动追加前缀                                                                                                                                        | string                                                                                        |
+| fieldStyle            | 整个 fieldWrapper 的 内联样式<br/> **v1.15.0开始提供**                                                                                                                                        | object                                                                                        |
+| initValue             | 该表单控件的初始值(仅在 Field mounted 时消费一次,后续更新无效),相比 Form 的 initValues 中的值,它的优先级更高                                                                                                   | any(类型取决于当前组件,详细见各组件的 api)                                                 |
+| validate              | 该表单控件的的自定义校验函数。支持同步、异步校验。<br/>设置了 validate 时,rules 不会生效<br/> 使用示例:(fieldValue, values) => fieldValue >= 5 ? 'value not valid': ''                                              | function(fieldValue, values)                                                                  |           |
+| rules                 | 校验规则,校验库基于[async-validator](https://github.com/yiminghe/async-validator) <br/> 使用示例:const rules=\[{ required: true, message: 'can't be null ' },<br/>{ max: 10, message: 'can't more than 10 word' }\] | array                                                                                         |           |
+| validateStatus        | 该表单控件的校验结果状态(仅影响样式),可选值:`success`/`error`/`warning`/`default`                                                                                                                                | string                                                                                        | 'default' |
+| trigger               | 触发校验的时机,可选值:`blur`/`change`/`custom`/`mount`,或以上值的组合\['blur','change'\]<br/>1、设置为 custom 时,仅会由 formApi/fieldApi 触发校验时被触发<br/>2、mount(挂载时即触发一次校验)                     | string/array                                                                                  | 'change'  |
+| onChange              | 值变化时触发的回调                                                                                                                                                                                                  | function(filedValue: any \| ev: { target: { value: any }}) (具体参见各组件的 onChange 方法) |
+| onBlur                | 失去焦点时触发的回调                                                                                                                                                                                                | function() (具体参见各组件的 onBlur 方法)                                                   |
+| transform             | 校验前转换字段值,转换后的值仅会在校验时被消费,对 formState 无影响<br/> 使用示例: (value) => Number                                                                                                                 | function(fieldValue)                                                                          |           |
+| convert               | field 值改变后,在 rerender 前,对 filed 的值进行二次更新<br/> 使用示例: (value) => newValue                                                                                                                         | function(fieldValue)                                                                          |           |
+| allowEmptyString      | 是否允许值为空字符串。默认情况下值为''时,该 field 对应的 key 会从 values 中移除,如果你希望保留该 key,那么需要将 allowEmptyString 设为 true                                                                       | boolean                                                                                       | false     |
+| stopValidateWithError | 为 true 时,使用 rules 校验,碰到第一个检验不通过的 rules 后,将不再触发后续 rules 的校验<br/>**v0.35.0 开始提供**                                                                                                  | boolean                                                                                       | false     |
+| helpText              | 自定义提示信息,与校验信息公用同一区块展示,两者均有值时,优先展示校验信息<br/>**v1.0.0 开始提供**                                                                                                                  | ReactNode                                                                                     |           |
+| extraText             | 额外的提示信息,当需要错误信息和提示文案同时出现时,可以使用这个,位于 helpText/errorMessage 后<br/>**v1.0.0 开始提供**                                                                                             | ReactNode                                                                                     |           |
+| pure                  | 是否仅接管数据流,为 true 时不会自动插入 ErrorMessage、Label、extraText 等模块,样式、DOM 结构与原始的组件保持一致<br/>**v1.1.0 开始提供**                                                                          | boolean                                                                                       | false     |
+| extraTextPosition     | 控制extraText的显示位置,可选`middle`(垂直方向以Label、extraText、Field主体的顺序显示)、`bottom` (垂直方向以Label、Field主体、extraText的顺序显示);在Form与Field上同时传入时,以Field props为准<br/>**v1.9.0 开始提供**                                                                          | string                                                                                       | 'bottom'     |
+| ...other              | 组件的其他可配置属性,与上面的属性平级一并传入即可,例如 Input 的 size/placeholder,**Field 会将其透传至组件本身**                                                                                                  |                                                                                               |
+
+
+
+## Form.Section
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Section } = Form;
+```
+
+| 属性      | 说明     | 类型      | 版本|
+| --------- | -------- | --------- |---- |
+| text      | 段落标题 | ReactNode | v1.0.0|
+| className | 样式类名 | string    | v1.0.0|
+| style     | 内联样式 | object    | v1.0.0|
+| children  | 段落内容 | ReactNode | v1.0.0|
+
+## Form.Label
+
+默认情况下,Label 会由 Form 自行插入到每个 Field 中。如果你需要在其他地方自行插入 Label,我们提供了 Label 组件可以导出
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Label } = Form;
+```
+
+| 属性      | 说明                     | 类型      | 默认值 | 版本|
+| --------- | ------------------------ | --------- | ------ |--- |
+| text      | Label 内容               | ReactNode |        |  |
+| required  | 是否展示必填的\*号       | boolean   | false  |  |
+| extra     | 跟随在 required 后的内容 | ReactNode |        | v0.33.0 |
+| align     | text-align               | string    | 'left' |  |
+| className | 样式类名                 | string    |        |  |
+| style     | 内联样式                 | string    |        |  |
+| width     | label 宽度               | number    |        |  |
+
+## Form.Slot
+
+> Form.Slot 在 v0.27.0 开始提供
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { Slot } = Form;
+```
+
+| 属性          | 说明                                                                                                                               | 类型           |
+| ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------- |
+| label         | slot 的[Label 配置](#Form.Label), 例如{ text: 'semi', align: 'left' };也可以直接传入 string,Slot 内部会自动封装成合法 Label 格式 | object\|string |
+| labelPosition | slot 的 label 位置,默认情况下继承自 form props,也可单独覆盖。可选'top'、'left'                                                   | string         |  |
+| className     | slot 样式类名                                                                                                                      | string         |
+| style         | slot 内联样式                                                                                                                      | object         |
+| children      | slot 的主体内容                                                                                                                    | ReactNode      |
+
+## Form.ErrorMessage
+
+> Form.ErrorMessage 在 v0.27.0 开始提供
+
+```jsx
+import { Form } from '@douyinfe/semi-ui';
+const { ErrorMessage } = Form;
+```
+
+-   当 error 为 ReactNode、String、boolean 时,直接渲染
+-   当 error 为数组时,会自动执行 join 操作聚合数组内的错误信息
+
+| 属性             | 说明                                                      | 类型                     |
+| ---------------- | --------------------------------------------------------- | ------------------------ |
+| error            | 错误信息内容                                              | string\|array\|ReactNode\|undefined\|boolean |
+| className        | 样式类名                                                  | string                   |
+| style            | 内联样式                                                  | object                   |
+| showValidateIcon | 自动加上 validateStatus 对应的 icon                       | boolean                  |
+| validateStatus   | 信息所属的校验状态,可选 default/error/warning/success(success一般建议与default样式相同) | boolean                  |
+
+## withFieldOptions
+
+| key               | 描述                                                                                                                                                                                                                                          | 默认值     |
+| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| valueKey          | 组件表示值的属性,如 Switch、Radio 的是'checked',Input 的是'value'                                                                                                                                                                           | 'value'    |
+| onKeyChangeFnName | 组件值变化时的回调函数,一般为'onChange'                                                                                                                                                                                                      | 'onChange' |
+| valuePath         | 值属性在回调函数中第一个参数的路径,如 Radio 的 onChange(e.target.checked),那么该值需要设为 target.checkd;RadioGroup 的 onChange(e.target.value),该值为'target.value';若第一个参数就是值本身,无需再往下取值,该项不需要设                 |            |
+| maintainCursor    | 是否需要保持光标,用于 Input 类组件                                                                                                                                                                                                           | false      |
+| shouldMemo        | 是否需要 memo(用于表单性能优化,避免 Form rerender 时 Field 也被 rerender),对于有内部状态且内部状态可能会更新并影响 UI 的自定义组件,此项应该置为 false <br/>**v0.27.0 后提供** | true       |
+
+## 设计变量
+<DesignToken/>
+
+## FAQ
+
+-   **为什么我声明了表单,对值进行了修改,数据没有自动映射到 formState.values 中?**  
+     请检查是否正确传入了 field,Field 上的`field`属性是必填项!!!
+
+-   **为什么传入了 defaultValue、defaultChecked 不生效?**  
+     请参考文档开头[表单控件](#声明表单的多种写法),Form.Field 组件对默认值做了统一处理,你应该使用`initValue`或者`initValues`来传入默认值
+
+-   **为什么异步更新了 initValue、initValues 后,组件没有发生变化,值没有生效?**  
+     `initValue`、`initValues`只在 Field、Form mounted 时进行消费,后续做的异步更新并不会起效。  
+     如果你的初始值需要从远程取,那么你可以在获取到值之后,使用`formApi.setValue/setValues`进行更新。  
+     或者直接给 Form、Field 传入一个新的`key`强制它重新挂载
+
+-   **为什么调用了 formApi.setValues 更新 fields 的值,但是实际渲染并没有更新?**
+
+    setValues 默认情况下对尚未存在的 field 进行赋值不会生效。如果你的 fields 是动态加载的话,请检查在 setValues 时,该 field 是否已 mounted。  
+    如有需要,可以使用 override 模式 `formApi.setValues(newValue, { isOverride: true })`
+
+-   **为什么 rules 中的 validator 校验失败,但是对应的错误信息没有被展示?**
+
+    async-validator 的自定义 validator 返回值必须是 boolean 类型,否则它不执行任何回调,semi 后续的钩子也不会被调用。建议通过加 !! 或者 Boolean() 强制转换返回类型
+
+-   **为什么 getValues 拿不到某个 field?**
+
+    field 没有初始值的话,`getValues` 获取不到这一项。可以设置 `initValues`/`initValue` 或者给 form 设置 `allowEmpty` 属性。
+
+-   **[🔍 🧾 更多Form FAQ补充 & 问题自查手册](https://bytedance.feishu.cn/docs/doccnNKaGhZMqyu0FufD1JGHOjf)** 
+    

+ 452 - 0
content/input/input/index-en-US.md

@@ -0,0 +1,452 @@
+---
+localeCode: en-US
+order: 21
+category: Input
+title:  Input
+subTitle: Input
+icon: doc-input
+width: 60%
+brief: Input is a basic component for users to enter and edit text.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { Input } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input defaultValue='hi' autofocus></Input>
+)
+```
+
+### Size
+
+Support three sizes: `large`, `default`, and `small`.
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Input placeholder='large' size='large'></Input>
+    <br/><br/>
+    <Input placeholder='default'></Input>
+    <br/><br/>
+    <Input placeholder='small' size='small'></Input>
+  </>
+)
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Input defaultValue='enabled input'></Input>
+    <br/>
+    <br/>
+    <Input disabled defaultValue='disbaled input'></Input>
+  </>
+)
+```
+
+### Prefix/Suffix
+
+```jsx live=true
+import React from 'react';
+import { Input, Typography } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+() => (
+  <>
+    <Input prefix={<IconSearch />} showClear></Input>
+    <br/><br/>
+    <Input prefix="Prefix" showClear></Input>
+    <br/><br/>
+    <Input suffix={<IconSearch />} showClear></Input>
+    <br/><br/>
+    <Input suffix={<Typography.Text strong type='secondary' style={{ marginRight: 8 }}>Suffix</Typography.Text>} showClear></Input>
+  </>
+)
+```
+
+### Addon
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+() => (
+  <Input addonBefore="http://" addonAfter=".com" />
+)
+```
+
+### Clear Icon
+
+Use `showClear` to allow clear current value when clicking on clear icon.
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input showClear defaultValue='click to clear'></Input>
+)
+```
+
+### Password Mode
+
+Hide the content of input
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input mode="password" defaultValue="123456"></Input>
+)
+```
+
+### Validation
+
+You can set different `validateStatus` to provide style feedback to the user.
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+() => (
+  <>
+    <Input defaultValue='ies' validateStatus='warning'></Input>
+    <br/><br/>
+    <Input defaultValue='ies' validateStatus='error'></Input>
+    <br/><br/>
+    <Input defaultValue='ies'></Input>
+  </>
+)
+```
+
+### Controlled Component
+
+You can use `value` along with `onChange` property if you want to use Input as a controlled component.
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+class InputDemo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: 'controlInput',
+            value2: 'input'
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(value, e) {
+      console.log(value)
+      this.setState({ value });
+    }
+    render() {
+        return (
+            <>
+              <Input
+                  value={this.state.value}
+                  onChange={this.onChange}>
+              </Input>
+            </>
+        )
+    }
+}
+```
+
+### InputGroup
+
+You could put multiple text field input into `<InputGroup>` and set `size`, `disabled` to the entire group. Supported fields include: `Input`, `InputNumber`, `Select`, `AutoComplete`、`TreeSelect`、`Cascader`、`DatePicker`
+
+<Notice type="primary" title="Notice">
+  <div>InputGroup does not recommend inserting non-supported elements. Form.InputGroup will perform error aggregation on supported elements without customizing the elements for processing.</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { Input, InputGroup, InputNumber, Select, AutoComplete, DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <InputGroup>
+      <Input placeholder="Name" style={{ width: 100 }} />
+      <InputNumber placeholder="Score" style={{ width: 140 }} />
+    </InputGroup>
+    <br/><br/><br/>
+    <InputGroup size={'small'}>
+      <Select style={{ width: '100px' }} defaultValue='home'>
+          <Select.Option value='home'>Home</Select.Option>
+          <Select.Option value='work'>Work</Select.Option>
+      </Select>
+      <AutoComplete
+          data={['Beijing Haidian']}
+          placeholder='Address: '
+          style={{ width: 180 }}
+      >
+      </AutoComplete>
+    </InputGroup>
+    <br/><br/><br/>
+    <InputGroup size={'small'}>
+      <Select style={{ width: '100px' }} defaultValue='signup'>
+          <Select.Option value='signup'>Sign Up</Select.Option>
+          <Select.Option value='signin'>Sign In</Select.Option>
+      </Select>
+      <Input placeholder="Email" style={{ width: 180 }} />
+    </InputGroup>
+    <br/><br/><br/>
+    <InputGroup size={'small'}>
+      <Input placeholder="Name" style={{ width: 100 }} />
+      <DatePicker placeholder="Birthday" />
+    </InputGroup>
+  </div>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Input, InputGroup, Select, Cascader } from '@douyinfe/semi-ui';
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    { label: 'Beijing', value: 'Beijing', key: '0-0-0' },
+                    { label: 'Shanghai', value: 'Shanghai', key: '0-0-1' },
+                ],
+            },
+        ],
+    },
+    { label: 'North America', value: 'North America', key: '1' }
+  ];
+  return (
+    <>
+      <InputGroup>
+        <Select style={{ width: 100 }} defaultValue='from'>
+          <Select.Option value='from'>From: </Select.Option>
+          <Select.Option value='to'>To: </Select.Option>
+        </Select>
+        <TreeSelect
+          style={{ width: 220 }}
+          treeData={treeData}
+          placeholder="Please select"
+        />
+      </InputGroup>
+      <br/><br/>
+
+      <InputGroup>
+          <Select style={{ width: 100 }} defaultValue='from'>
+          <Select.Option value='from'>From: </Select.Option>
+          <Select.Option value='to'>To: </Select.Option>
+        </Select>
+          <Cascader
+              style={{ width: 220 }}
+              treeData={treeData}
+              placeholder="Please select"
+          />
+      </InputGroup>
+    </>
+  )
+}
+
+```
+
+### TextArea
+
+Used for multi-line text. You can set `maxCount` to restrict text entering and display text count. Since 1.30.0, `showClear` is supported.
+
+```jsx live=true
+import React from 'react';
+import { TextArea } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <TextArea />
+    <br/><br/>
+    <TextArea maxCount={100} showClear/>
+  </div>
+)
+```
+
+### Autosize TextArea
+
+You can set `autosize` to allow TextArea resizing height with content.
+
+```jsx live=true
+import React from 'react';
+import { TextArea } from '@douyinfe/semi-ui';
+() => (
+  <div>
+    <TextArea autosize rows={1} />
+    <br/><br/>
+    <TextArea autosize maxCount={100} />
+  </div>
+)
+```
+
+### Custom calculated character string length
+
+By setting the getValueLength property, you can customize the length of the character string. With maxLength and minLength, you can support emoji length to calculate according to the visible length.
+
+
+What is done inside Semi when getValueLength is passed in:
+
+- maxLength: maxLength is not passed directly to the native input. If the input length exceeds the maximum limit, the legal length character entered last time is used.
+- minLength: dynamically switch the length of minLength, emoji is calculated according to a length.
+- maxCount: compare the values obtained using getValueLength with maxCount
+
+```jsx live=true
+import React from 'react';
+import { Input, Typography, Form, Button, TextArea } from '@douyinfe/semi-ui';
+import GraphemeSplitter from 'grapheme-splitter';
+
+() => {
+  const [value, setValue] = useState();
+  function getValueLength(str) {
+    if (typeof str === 'string') {
+      const splitter = new GraphemeSplitter();
+      return splitter.countGraphemes(str);
+    } else {
+      return 0;
+    }
+  }
+
+  function getTextAreaStrLength(str) {
+    const filteredStr = str.replace(/\s/g, '');
+    return filteredStr.length;
+  }
+
+  return (
+    <div>
+      <h4>maxLength=10</h4>
+      <div>
+        <Typography.Text>Please input following emoji</Typography.Text>
+        <div><Typography.Text copyable>💖</Typography.Text></div>
+        <div><Typography.Text copyable>👨‍👩‍👧‍👦</Typography.Text></div>
+      </div>
+      <Input maxLength={10} getValueLength={getValueLength} onChange={setValue} style={{ width: 200, marginTop: 12, marginBottom: 12 }} />
+      {
+        value && (
+          <div>
+            <div><Typography.Text type="tertiary">{`getValueLength=${getValueLength(value)}`}</Typography.Text></div>
+            <div><Typography.Text type="tertiary">{`length=${value.length}`}</Typography.Text></div>
+          </div>
+        )
+      }
+      <br/><br/>
+      <h4>Form.Input + minLength=4</h4>
+      <Form layout="horizontal">
+        <Form.Input noLabel field="username" minLength={4} getValueLength={getValueLength} style={{ width: 200 }} />
+        <Button type="primary" htmlType="submit">Submit</Button>
+      </Form>
+      <h4>maxCount=10</h4>
+      <TextArea defaultValue="semi design" rows={2} maxCount={10} getValueLength={getTextAreaStrLength} style={{ width: 200 }} />
+    </div>
+  );
+}
+```
+
+Answers to some questions:
+
+> Why not just import the `grapheme-splitter` package? The uncompressed size of this package is 200+ kB, which is a bit too large for users who do not need to calculate emoji according to the visible length. Therefore, Semi chose to use the length calculation function as an argument for users to pass in
+
+> Why not modify maxLength dynamically? Modify maxLength dynamically after the input operation is completed, calculate the remaining character length that can be entered. If the maxLength is set to 1, you want to enter a '💖' with a length of 2, but due to the limitation of input maxLength, you can't enter it at all here, and you can't update maxLength.
+
+
+## API Reference
+
+### Input
+
+> Other attributes are same with html `<input>`
+
+| Property       | Instructions                                                                                  | type                            | Default   |
+|----------------|-----------------------------------------------------------------------------------------------|---------------------------------|-----------|
+| addonAfter     | Addon after input box                                                                         | ReactNode               |           |
+| addonBefore    | Addon before input box                                                                        | ReactNode               |           |
+| className      | Class name                                                                                    | string                          |           |
+| defaultValue   | Default value                                                                                 | ReactText                          |           |
+| disabled       | Toggle whether to disable input                                                               | boolean                         | false     |
+| getValueLength | Custom calculated character string length                                            | (value: string) => number        |      |
+| hideSuffix     | Toggle whether to hide suffix if clear icon is shown,by default the two icon are side by side | boolean                         | false     |
+| mode           | The mode of the input box. The optional value is `password`                                   | string                          |           |
+| mode           | mode of input,optional: `password` **>= v1.3.0**                                              | string                          |           |
+| prefix         | Prefix                                                                                        | ReactNode               |           |
+| showClear      | Show clear button **>=1.0.0**                                                                 | boolean                         | false     |
+| size           | Size, one of `large`, `default`, `small`                                                      | string                          | `default` |
+| style          | Inline style                                                                                  | CSSProperties                          |           |
+| suffix         | Suffix                                                                                        | ReactNode               |           |
+| type           | Input type attribute, same with html `<input>`                                                | string                          | text      |
+| validateStatus | Validate status for styling only, one of `default`, `error`, `warning`                        | string                          | `default` |
+| value          | Current value of input box                                                                    | ReactText                          |           |
+| onBlur         | Callback invoked when input loses focus                                                       | function(e:event)                        |           |
+| onChange       | Callback invoked when input value changes                                                     | function(value:string, e:event) |           |
+| onClear        | Callback invoked when clicking clear icon                                                     | function(e:event)                        |           |
+| onEnterPress   | Callback invoked when pressing enter(keypress)                                                | function(e:event)               |           |
+| onFocus        | Callback invoked when input gets focus                                                        | function(e:event)                        |           |
+| onKeyDown      | Callback invoked when keydown                                                                 | function(e:event)               |           |
+| onKeyPress     | Callback invoked when keypress                                                                | function(e:event)               |           |
+| onKeyUp        | Callback invoked when keyup                                                                   | function(e:event)               |           |
+### TextArea
+
+> Other attributes are same with html `<textarea>`
+
+| Property     | Instructions                                                                                                           | type                            | Default |
+|--------------|------------------------------------------------------------------------------------------------------------------------|---------------------------------|---------|
+| autosize     | Toggle whether to allow autosize when content height changes                                                           | boolean                         | false   |
+| className    | Class name                                                                                                             | string                          | -       |
+| cols         | The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. | number                          | -       |
+| disabled     | Disabled                                                                                                               | boolean                         | false   |
+| getValueLength | Custom calculated character string length                                            | (value: string) => number        |      |
+| maxCount     | The maximum number of characters and display count                                                                     | number                          | -       |
+| placeholder  | Content to be appear by default                                                                                        | string                          | -       |
+| readonly     | Read-only, not editable                                                                                                | boolean                         | false   |
+| rows         | The number of visible text lines for the control.                                                                      | number                          | 4       |
+| showClear      | Show clear button **>=1.30.0**                                                                 | boolean                         | false     |
+| style        | Inline style                                                                                                           | CSSProperties                          | -       |
+| onBlur       | Callback invoked when input loses focus                                                                                | (e:event) => void               | -       |
+| onChange     | Callback invoked when input value changes                                                                              | (value:string, e:event) => void  |         |
+| onClear      | Callback invoked when clicking clear icon  **>=1.30.0**                                                       | (e:event) => void                        |           |
+| onEnterPress | Callback invoked when pressing enter                                                                                   | (e:event) => void                        | -       |
+| onFocus      | Callback invoked when input gets focus                                                                                 | (e:event) => void               | -       |
+| onKeyDown    | Callback invoked when keydown, html event                                                                              | (e:event) => void               | -       |
+| onKeyPress   | Callback invoked when keypress, html event                                                                             | (e:event) => void               | -       |
+| onKeyUp      | Callback invoked when keyup, html event                                                                                | (e:event) => void               | -       |
+| onResize     | Callback invoked when height changes in autosize mode **v>=0.37.0**                                                    | ({ height:number }) => void     | -       |
+## Methods
+
+| Name    | Description  |
+|---------|--------------|
+| blur()  | Remove focus |
+| focus() | Get focus    |
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+```material
+44, 46
+``` -->

+ 461 - 0
content/input/input/index.md

@@ -0,0 +1,461 @@
+---
+localeCode: zh-CN
+order: 21
+category: 输入类
+title:  Input 输入框
+icon: doc-input
+width: 60%
+brief: 输入框是最基本的接收用户文本输入的组件
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Input } from '@douyinfe/semi-ui';
+```
+### 基本
+
+基本使用
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input defaultValue='hi' autofocus></Input>
+)
+```
+
+### 三种大小
+
+默认定义了三种尺寸:大、默认、小
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Input placeholder='large' size='large'></Input>
+    <br/><br/>
+    <Input placeholder='default'></Input>
+    <br/><br/>
+    <Input placeholder='small' size='small'></Input>
+  </>
+)
+```
+
+### 不可用
+
+设定 `disabled` 属性为 `true`
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Input defaultValue='enabled input'></Input>
+    <br/>
+    <br/>
+    <Input disabled defaultValue='disbaled input'></Input>
+  </>
+)
+```
+
+### 前缀/后缀
+
+在输入框上增加前缀、后缀图标,可以是 ReactNode 。
+
+```jsx live=true
+import React from 'react';
+import { Input, Typography } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+() => (
+  <>
+    <Input prefix={<IconSearch />} showClear></Input>
+    <br/><br/>
+    <Input prefix="Prefix" showClear></Input>
+    <br/><br/>
+    <Input suffix={<IconSearch />} showClear></Input>
+    <br/><br/>
+    <Input suffix={<Typography.Text strong type='secondary' style={{ marginRight: 8 }}>Suffix</Typography.Text>} showClear></Input>
+  </>
+)
+```
+
+### 前置/后置标签
+
+在输入框上增加前置/后置标签
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input addonBefore="http://" addonAfter=".com" />
+)
+```
+
+### 带移除图标
+
+点击图标删除所有内容
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input showClear defaultValue='click to clear'></Input>
+)
+```
+
+### 密码模式
+
+隐藏输入的具体内容
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <Input mode="password" defaultValue="123456"></Input>
+)
+```
+
+
+### 校验状态
+
+可设置不同校验状态,展示不同样式
+
+```jsx live=true
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Input defaultValue='ies' validateStatus='warning'></Input>
+    <br/><br/>
+    <Input defaultValue='ies' validateStatus='error'></Input>
+    <br/><br/>
+    <Input defaultValue='ies'></Input>
+  </>
+)
+```
+
+### 受控组件
+
+`Input` 值完全取决于传入的 `value` 值,配合 `onChange` 回调函数使用
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Input } from '@douyinfe/semi-ui';
+
+class InputDemo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: 'controlInput',
+            value2: 'input'
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(value, e) {
+      console.log(value)
+      this.setState({ value });
+    }
+    render() {
+        return (
+            <>
+              <Input
+                  value={this.state.value}
+                  onChange={this.onChange}>
+              </Input>
+            </>
+        )
+    }
+}
+```
+
+### 输入框组合
+
+可以将多个输入框放入 InputGroup 的容器中,通过设置 `size` ,`disabled` 可统一设置组合中的输入框属性,支持输入框类型包括: `Input`, `InputNumber`, `Select`, `AutoComplete`、`TreeSelect`、`Cascader`、`DatePicker`
+
+<Notice type="primary" title="注意事项">
+  <div>InputGroup 不推荐插入非支持元素,Form.InputGroup 会对支持的元素进行错误聚合,而不会自定义元素进行处理。</div>
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { InputGroup, Input, InputNumber, Input, AutoComplete, DatePicker } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+      <InputGroup>
+        <Input placeholder="Name" style={{ width: 100 }} />
+        <InputNumber placeholder="Score" style={{ width: 140 }} />
+      </InputGroup>
+      <br/><br/><br/>
+      <InputGroup size={'small'}>
+        <Select style={{ width: '100px' }} defaultValue='home'>
+            <Select.Option value='home'>Home</Select.Option>
+            <Select.Option value='work'>Work</Select.Option>
+        </Select>
+        <AutoComplete
+            data={['Beijing Haidian']}
+            placeholder='Address: '
+            style={{ width: 180 }}
+        >
+        </AutoComplete>
+      </InputGroup>
+      <br/><br/><br/>
+      <InputGroup size={'small'}>
+        <Select style={{ width: '100px' }} defaultValue='signup'>
+            <Select.Option value='signup'>Sign Up</Select.Option>
+            <Select.Option value='signin'>Sign In</Select.Option>
+        </Select>
+        <Input placeholder="Email" style={{ width: 180 }} />
+      </InputGroup>
+      <br/><br/><br/>
+      <InputGroup size={'small'}>
+        <Input placeholder="Name" style={{ width: 100 }} />
+        <DatePicker placeholder="Birthday" />
+      </InputGroup>
+    </div>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { InputGroup, Select, Cascader } from '@douyinfe/semi-ui';
+
+() => {
+  const Option = Select.Option;
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    { label: 'Beijing', value: 'Beijing', key: '0-0-0' },
+                    { label: 'Shanghai', value: 'Shanghai', key: '0-0-1' },
+                ],
+            },
+        ],
+    },
+    { label: 'North America', value: 'North America', key: '1' }
+  ];
+  return (
+    <>
+      <InputGroup>
+        <Select style={{ width: 100 }} defaultValue='from'>
+          <Select.Option value='from'>From: </Select.Option>
+          <Select.Option value='to'>To: </Select.Option>
+        </Select>
+        <TreeSelect
+          style={{ width: 220 }}
+          treeData={treeData}
+          placeholder="Please select"
+        />
+      </InputGroup>
+      <br/><br/>
+      <InputGroup>
+          <Select style={{ width: 100 }} defaultValue='from'>
+            <Select.Option value='from'>From: </Select.Option>
+            <Select.Option value='to'>To: </Select.Option>
+          </Select>
+          <Cascader
+              style={{ width: 220 }}
+              treeData={treeData}
+              placeholder="Please select"
+          />
+      </InputGroup>
+    </>
+  )
+}
+
+```
+
+### 多行输入框
+
+用于多行输入。通过设置 `maxCount` 属性可以进行字数限制并显示字数统计。1.30.0 开始支持 `showClear`。
+
+```jsx live=true
+import React from 'react';
+import { TextArea } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <TextArea />
+    <br/><br/>
+    <TextArea maxCount={100} showClear/>
+  </div>
+)
+```
+
+### 自动扩展的多行输入框
+
+通过设置 `autosize` 属性可设置只有高度自动随内容增加而变化。
+
+```jsx live=true
+import React from 'react';
+import { TextArea } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <TextArea autosize rows={1} />
+    <br/><br/>
+    <TextArea autosize maxCount={100} />
+  </div>
+)
+```
+
+### 自定义计算字符串长度
+
+通过设置 `getValueLength` 属性可以自定义计算字符串长度。搭配 maxLength 和 minLength 可以支持 emoji 长度按照可见长度计算。
+
+
+传入 getValueLength 时,Semi 内部做了什么:
+
+- maxLength:不直接透传 maxLength 给原生 input。如果输入长度超出最大限制,则使用上一次输入的合法长度字符。
+- minLength:动态切换 minLength 的长度,emoji 按照一个长度计算。
+- maxCount:使用 getValueLength 获取的值与 maxCount 进行比较
+
+```jsx live=true
+import React from 'react';
+import GraphemeSplitter from 'grapheme-splitter';
+import { Input, Typography, Form, TextArea, Button } from '@douyinfe/semi-ui';
+
+() => {
+  const [value, setValue] = useState();
+  function getValueLength(str) {
+    if (typeof str === 'string') {
+      const splitter = new GraphemeSplitter();
+      return splitter.countGraphemes(str);
+    } else {
+      return 0;
+    }
+  }
+
+  function getTextAreaStrLength(str) {
+    const filteredStr = str.replace(/\s/g, '');
+    return filteredStr.length;
+  }
+
+  return (
+    <div>
+      <h4>maxLength=10</h4>
+      <div>
+        <Typography.Text>尝试输入以下字符</Typography.Text>
+        <div><Typography.Text copyable>💖</Typography.Text></div>
+        <div><Typography.Text copyable>👨‍👩‍👧‍👦</Typography.Text></div>
+      </div>
+      <Input maxLength={10} getValueLength={getValueLength} onChange={setValue} style={{ width: 200, marginTop: 12, marginBottom: 12 }} />
+      {
+        value && (
+          <div>
+            <div><Typography.Text type="tertiary">{`getValueLength=${getValueLength(value)}`}</Typography.Text></div>
+            <div><Typography.Text type="tertiary">{`length=${value.length}`}</Typography.Text></div>
+          </div>
+        )
+      }
+      <br/><br/>
+      <h4>Form.Input + minLength=4</h4>
+      <Form layout="horizontal">
+        <Form.Input noLabel field="username" minLength={4} getValueLength={getValueLength} style={{ width: 200 }} />
+        <Button type="primary" htmlType="submit">提交</Button>
+      </Form>
+      <h4>maxCount=10</h4>
+      <TextArea defaultValue="semi design" rows={2} maxCount={10} getValueLength={getTextAreaStrLength} style={{ width: 200 }} />
+    </div>
+  );
+}
+```
+
+一些问题的回答:
+
+> 为何不直接引入 `grapheme-splitter` 包?这个包未压缩体积为 200+kB,对于不需要把 emoji 按照可见长度计算的用户来说,这个体积有点过大了。因此 Semi 选择把长度计算函数作为参数让用户传入。
+
+> 为何不动态修改 maxLength?动态修改 maxLength 在输入操作完成以后,计算剩余可以输入的字符长度。 如 maxLength 设置为 1,想输入一个 length 为 2 的 '💖',但是由于 input maxLength 的限制,这里根本就输入不进去,也就无法更新 maxLength。
+
+## API 参考
+
+### Input
+> 其他属性与html input 标签保持一致
+
+| 属性           | 说明                                                            | 类型                            | 默认值    |
+|----------------|---------------------------------------------------------------|---------------------------------|-----------|
+| addonAfter     | 后置标签                                                        | ReactNode               |           |
+| addonBefore    | 前置标签                                                        | ReactNode               |           |
+| className      | 类名                                                            | string                          |           |
+| defaultValue   | 输入框内容默认值                                                | ReactText                          |           |
+| disabled       | 是否禁用,默认为false                                            | boolean                         | false     |
+| getValueLength| 自定义计算字符串长度                                            | (value: string) => number        |      |
+| hideSuffix     | 清除按钮与后缀标签并存时隐藏后缀标签,默认为false两者并列        | boolean                         | false     |
+| mode           | 输入框的模式,可选值password **>=v1.3.0**                        | string                          |           |
+| prefix         | 前缀标签                                                        | ReactNode               |           |
+| showClear      | 支持清除 **>=1.0.0**                                            | boolean                         | false     |
+| size           | 输入框大小,large、default、small                                  | string                          | 'default' |
+| style          | 样式                                                            | CSSProperties                          |           |
+| suffix         | 后缀标签                                                        | ReactNode               |           |
+| type           | 声明input类型,同原生input标签的type属性                         | string                         | text     |
+| validateStatus | 校验状态,可选值default、error、warning,默认default。仅影响展示样式 | string                          | 'default' |
+| value          | 输入框内容                                                      | ReactText                          |           |
+| onBlur         | 输入框失去焦点时的回调                                          | function(e:event)                        |           |
+| onChange       | 输入框内容变化时的回调                                          | function(value:string, e:event) |           |
+| onClear        | 点击清除按钮时的回调                                            | function(e:event)                        |           |
+| onEnterPress   | 按回车时回调(keypress)                                          | function(e:event)               |           |
+| onFocus        | 输入框focus时的回调                                             | function(e:event)                        |           |
+| onKeyDown      | keydown回调                                                     | function(e:event)               |           |
+| onKeyPress     | keypress回调                                                    | function(e:event)               |           |
+| onKeyUp        | keyup回调                                                       | function(e:event)               |           |
+### TextArea
+
+> 其他属性与 html textarea 标签保持一致
+
+| 属性         | 说明                               | 类型                            | 默认值 |
+|--------------|----------------------------------|---------------------------------|--------|
+| autosize     | 是否随着自动适应内容高度           | boolean                         | false  |
+| className    | 类名                               | string                          | -      |
+| cols         | 默认列数                           | number                          | 无     |
+| disabled     | 禁用状态                           | boolean                         | false  |
+| getValueLength| 自定义计算字符串长度                                            | (value: string) => number        |      |
+| maxCount     | 设置字数限制并显示字数统计         | number                          | 无     |
+| placeholder  | 当前的默认值                       | string                          | 无     |
+| readonly     | 只读                               | boolean                         | false  |
+| rows         | 默认行数                           | number                          | 4      |
+| showClear    | 支持清除 **>=1.30.0**               | boolean                         | false     |
+| style        | 样式                               | CSSProperties                   | -      |
+| onBlur       | 输入框失去焦点时的回调             |(e:event) => void               | -      |
+| onChange     | 输入框内容变化时的回调             | (value:string, e:event) => void |        |
+| onClear      | 点击清除按钮时的回调  **>=1.30.0** | (e:event) => void                         | -       |
+| onEnterPress | 按下回车的回调                     | (e:event) => void                         | 无     |
+| onFocus      | 输入框 focus 时的回调              | (e:event) => void               | -      |
+| onKeyDown    | keydown 回调,html 事件             | (e:event) => void               | -      |
+| onKeyPress   | keypress 回调,html 事件            | (e:event) => void               | -      |
+| onKeyUp      | keyup 回调,html 事件               | (e:event) => void               | -      |
+| onResize     | 触发高度变化时的回调 **>=v0.37.0** | ({ height:number }) => void    | -      |
+## Methods
+
+| 名称    | 描述     |
+|---------|--------|
+| blur()  | 移出焦点 |
+| focus() | 获取焦点 |
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+```material
+44, 46
+``` -->
+

+ 242 - 0
content/input/inputnumber/index-en-US.md

@@ -0,0 +1,242 @@
+---
+localeCode: en-US
+order: 22
+category: Input
+title:  InputNumber
+subTitle: InputNumber
+icon: doc-inputnumber
+brief: Enter values within range through a mouse or keyboard.
+---
+
+
+## When to Use
+
+When you need to get a standard value.
+
+## Demos
+
+### How to import
+
+```jsx import 
+import { InputNumber } from '@douyinfe/semi-ui';
+```
+
+
+### Basic Input Box
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+  render() {
+    return (
+      <div style={{ width: 280 }}>
+        <label>Simple</label>
+        <InputNumber />
+        <br/><br/>
+
+        <label>Set step to 2 </label>
+        <InputNumber step={2} />
+        <br/><br/>
+
+        <label>Press shift key and click the button to increase/decrease the step size </label>
+        <InputNumber shiftStep={100} />
+        <br/><br/>
+
+        <label>Set min to 1, max to 10</label>
+        <InputNumber min={1} max={10} Default Value={1} />
+        <br/><br/>
+      </div>
+    );
+  }
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+  render() {
+    return (
+      <div style={{ width: 280 }}>
+        <label>Set defaultValue to 1 </label>
+        <InputNumber defaultValue={1} />
+        <br/><br/>
+
+        <label>Set disabled to true</label>
+        <InputNumber defaultValue={2} disabled />
+        <br/><br/>
+
+        <label>Set autofocus to true </label>
+        <InputNumber defaultValue={3} autofocus />
+        <br/><br/>
+
+        <label>Set precision to 2 </label>
+        <InputNumber precision={2} defaultValue={1.234} />
+        <br/><br/>
+
+        <label>Set innerButtons=true </label>
+        <InputNumber innerButtons={true} suffix={'Hour'} defaultValue={1} style={{ width: 190}} />
+        <br/>
+
+      </div>
+    );
+  }
+}
+```
+
+
+### Inner Buttons
+
+With `innerButtons`, you can hide the buttons on the right into the interior, which will only be displayed when hover occurs
+
+```jsx live=true
+import React from 'react';
+
+() => (
+  <InputNumber innerButtons style={{ width: 190}} />
+)
+```
+
+Set `hidebuttons` to `true` to hide the buttons completely
+
+```jsx live=true
+import React from 'react';
+
+() => (
+  <InputNumber hideButtons style={{ width: 190}} />
+)
+
+```
+
+### Size
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+  render() {
+    return (
+      <div style={{ width: 180 }}>
+        <label>size=default</label>
+        <InputNumber />
+        <br/><br/>
+
+        <label>size=large</label>
+        <InputNumber size="large" />
+        <br/><br/>
+
+        <label>size=small</label>
+        <InputNumber size="small" />
+        <br/>
+
+      </div>
+    );
+  }
+}
+```
+
+### Custom Display Format and Resolution
+
+> A pair of methods for `formatter` and `parser`, which generally need to be set at the same time, otherwise the value cannot be resolved correctly.
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+  log(v) {
+    console.log(`Changed to: [${typeof v}] ${v}`);
+  }
+
+  render() {
+    return (
+      <div style={{ width: 180 }}>
+        <label>RMB</label>
+        <InputNumber
+            onChange={this.log}
+            defaultValue={1000}
+            min={0}
+            formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
+            parser={value => value.replace(/\¥\s?|(,*)/g, '')}
+        />
+        <br/><br/>
+
+        <label>Custom string</label>
+        <InputNumber
+            onChange={this.log}
+            defaultValue={1111}
+            formatter={value => String(value).split('').join('-')}
+            parser={value => value.replace(/\-/g, '')}
+        />
+        <br/>
+
+      </div>
+    );
+  }
+}
+```
+
+### Can Only Enter Numbers
+With formatter and onNumberChange(**>=v1.9.0**), a pure digital input box can be implemented.
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+function Demo () {
+  return (
+    <InputNumber
+      formatter={value => `${value}`.replace(/\D/g, '')}
+      onNumberChange={number => console.log(number)}
+      min={0}
+      max={Number.MAX_SAFE_INTEGER}
+    />
+  );
+}
+```
+
+## API Reference
+
+| Properties   | Instructions                                                                                    | type                              | Default   | Version    |
+| ------------ | ----------------------------------------------------------------------------------------------- | --------------------------------- | --------- | ---------- |
+| autofocus    | Automatic access to focus                                                                       | boolean                           | false     |            |
+| className    | class name of InputNumber                                                               | string  | -      |
+| defaultValue | Default                                                                                         | number                            |           |            |
+| disabled     | Disabled status                                                                                 | boolean                           | false     |            |
+| formatter    | Specifies the format of the input box to display the value                                      | (value: number\|string) => string | -         |            |
+| hideButtons  | Hide the "up/down" button when passing `true`                                                   | boolean                           | false     | **1.0.0**  |
+| innerButtons  | Show the "up/down" button in input box when passing `true`                                 | boolean                           | false         | **1.5.0** |
+| insetLabel   | Prefix label, lower priority than `prefix`                                                      | string\|ReactNode                 |           |            |
+| keepFocus    | Keep the input box focused when you click the button                                        | boolean                 |     false               | **1.10.0** |
+| max          | Limit maximum value                                                                             | number                            | Infinity  |            |
+| min          | Limit minimum value                                                                             | number                            | -Infinity |            |
+| parser       | Specifies how to convert back number string from formatter and use them in conjunction with formatter | (value: string) => string         | -         |      |
+| precision    | Numerical precision                                                                             | number                            | -         |            |
+| prefixCls    | Prefix content                                                                                  | string\|ReactNode                 |           |            |
+| pressInterval| How often will the click event be triggered when the button is long pressed, in milliseconds                                   | number                 |   250        |           |
+| pressTimeout | When the button is long pressed, how long will the click event be triggered after the delay, in milliseconds                                               | number                 |     250      |           |
+| shiftStep    | Step size for pressing the shift key, it can be a decimal.                            | number                            | 1         | **1.5.0** |
+| showClear    | Do you show the clear button?                                                                   | boolean                           | false     | **0.35.0** |
+| size         | Enter box size, optional value: "default"\|"small"\|"large"                                     | string                            | 'default' |            |
+| step         | Each time you change the number of steps, it can be a decimal.                                  | number                            | 1         |            |
+| style        | Inline style of InputNumber                                                             | CSSProperties  | -      |
+| suffix       | Custom suffix                                                                                   | ReactNode                         |           |            |
+| value        | Current value                                                                                   | number                            |           |            |
+| onBlur       | Callback when focus is lost                                                                     | (e: domEvent) => void             | () => {}  | **1.0.0**  |
+| onChange     | Change callback                                                                                 | (value: number\|string) => void   | -         |            |
+| onFocus      | Callback when focus is obtained                                                                 | (e: domEvent) => void             | () => {}  | **1.0.0**  |
+| onNumberChange | Number change callback                                                 | (value: number) => void   |   -         |     **1.9.0**      |
+
+## Methods
+
+| Name    | Description     |
+| ------- | --------------- |
+| blur()  | Move the focus. |
+| focus() | Get the focus.  |
+
+## Design Tokens
+<DesignToken/>

+ 223 - 0
content/input/inputnumber/index.md

@@ -0,0 +1,223 @@
+---
+localeCode: zh-CN
+order: 22
+category: 输入类
+title: InputNumber 数字输入框
+icon: doc-inputnumber
+brief: 通过鼠标或键盘,输入范围内的数值。
+---
+
+
+## 何时使用
+
+当需要获取标准数值时。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { InputNumber } from '@douyinfe/semi-ui';
+```
+### 基本输入框
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 280 }}>
+      <label>简单数字输入框</label>
+      <InputNumber />
+      <br/><br/>
+
+      <label>设置了步长 step=2 </label>
+      <InputNumber step={2} />
+      <br/><br/>
+
+      <label>设置 shiftStep=100, 按住 shift 同时点击按钮,可以一次增加/减少100 </label>
+      <InputNumber shiftStep={100} />
+      <br/><br/>
+
+      <label>设置了上下界 min=1,max=10</label>
+      <InputNumber min={1} max={10} defaultValue={1} />
+      <br/><br/>
+    </div>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 280 }}>
+      <label>设置了默认值 defaultValue=1 </label>
+      <InputNumber defaultValue={1} />
+      <br/><br/>
+
+      <label>禁用 disabled=true</label>
+      <InputNumber defaultValue={2} disabled />
+      <br/><br/>
+
+      <label>自动获得焦点 autofocus=true </label>
+      <InputNumber defaultValue={3} autofocus />
+      <br/><br/>
+
+      <label>设置了小数位数 precision=2 </label>
+      <InputNumber precision={2} defaultValue={1.234} />
+      <br/><br/>
+
+      <label>设置了 innerButtons=true </label>
+      <InputNumber innerButtons={true} suffix={'小时'} defaultValue={1} style={{ width: 190}} />
+      <br/>
+    </div>
+)
+```
+
+
+### 隐藏步进器
+
+通过innerButtons,你可以将右侧的步进器隐藏进内部,仅hover时才会显示
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => (
+  <InputNumber innerButtons style={{ width: 190}} />
+)
+```
+
+hideButtons设为true,彻底隐藏步进器
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => (
+  <InputNumber hideButtons style={{ width: 190}} />
+)
+```
+
+### 尺寸
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => (
+    <div style={{ width: 180 }}>
+      <label>默认尺寸 size=default</label>
+      <InputNumber />
+      <br/><br/>
+
+      <label>大尺寸 size=large</label>
+      <InputNumber size="large" />
+      <br/><br/>
+
+      <label>小尺寸 size=small</label>
+      <InputNumber size="small" />
+      <br/>
+    </div>
+)
+```
+
+### 自定义显示格式与解析方式
+
+> formatter 和 parser 一对方法,一般需要同时设置,否则无法正确解析值
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+() => {
+  const log = (v) => {
+    console.log(`Changed to: [${typeof v}] ${v}`);
+  }
+
+  return (
+      <div style={{ width: 180 }}>
+        <label>人民币</label>
+        <InputNumber
+            onChange={this.log}
+            defaultValue={1000}
+            min={0}
+            formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
+            parser={value => value.replace(/\¥\s?|(,*)/g, '')}
+        />
+        <br/><br/>
+
+        <label>自定义串</label>
+        <InputNumber
+            onChange={this.log}
+            defaultValue={1111}
+            formatter={value => String(value).split('').join('-')}
+            parser={value => value.replace(/\-/g, '')}
+        />
+        <br/>
+      </div>
+  )
+}
+```
+
+### 纯数字输入框
+搭配 formatter 和 onNumberChange(**>=v1.9.0**) 可以实现纯数字输入框。
+
+```jsx live=true
+import React from 'react';
+import { InputNumber } from '@douyinfe/semi-ui';
+
+function Demo () {
+  return (
+    <InputNumber
+      formatter={value => `${value}`.replace(/\D/g, '')}
+      onNumberChange={number => console.log(number)}
+      min={0}
+      max={Number.MAX_SAFE_INTEGER}
+    />
+  );
+}
+```
+
+## API 参考
+
+| 属性         | 说明                                                           | 类型                              | 默认值    | 版本      |
+| ------------ | -------------------------------------------------------------- | --------------------------------- | --------- | --------- |
+| autofocus    | 自动获取焦点                                                   | boolean                           | false     |           |
+| className | 类名                                                               | string  | -      |
+| defaultValue | 默认值                                                         | number                            |           |           |
+| disabled     | 禁用                                                           | boolean                           | false     |           |
+| formatter    | 指定输入框展示值的格式                                         | (value: number\|string) => string | -         |           |
+| hideButtons  | 为 `true` 时隐藏 “上/下” 按钮                                  | boolean                           | false     | **1.0.0** |
+| innerButtons | 为 `true` 时 “上/下” 按钮显示在输入框内部                                  | boolean                           | false     | **1.5.0** |
+| insetLabel   | 前缀标签,优先级低于 `prefix`                                  | string\|ReactNode                 |           |           |
+| keepFocus    | 点击按钮时保持输入框聚焦                                        | boolean                 |     false      |   **1.10.0**        |
+| max          | 限定最大值                                                     | number                            | Infinity  |           |
+| min          | 限定最小值                                                     | number                            | -Infinity |           |
+| parser       | 指定从 `formatter` 里转换回数字串的方式,和 `formatter` 搭配使用 | (str: string) => string           | -         |           |
+| precision    | 数值精度                                                       | number                            | -         |           |
+| prefixCls    | 前缀内容                                                       | string\|ReactNode                 |           |           |
+| pressInterval| 长按按钮时,多久触发一次点击事件,单位毫秒                                   | number                 |   250        |           |
+| pressTimeout | 长按按钮时,延迟多久后触发点击事件,单位毫秒                                                      | number                 |     250      |           |
+| shiftStep    | 按住 shift 键每次改变步数,可以为小数                           | number                            | 1         | **1.5.0** |
+| showClear    | 是否显示清除按钮                                               | boolean                           | false     | **0.35.0**   |
+| size         | 输入框大小,可选值:"default"\|"small"\|"large"                | string                            | 'default' |           |
+| step         | 每次改变步数,可以为小数                                       | number                            | 1         |           |
+| style     | 样式                                                               | CSSProperties  | -      |
+| suffix       | 自定义后缀                                                     | ReactNode                         |           |           |
+| value        | 当前值                                                         | number                            |           |           |
+| onBlur       | 失去焦点时的回调                                               | (e: domEvent) => void             | () => {}  | **1.0.0** |
+| onChange     | 变化回调                                                       | (value: number\|string) => void   | -         |           |
+| onFocus      | 获得焦点时的回调                                               | (e: domEvent) => void             | () => {}  | **1.0.0** |
+| onNumberChange | 数字变化回调                                                  | (value: number) => void   | -         |     **1.9.0**      |
+
+## Methods
+
+| 名称    | 描述     |
+| ------- | -------- |
+| blur()  | 移出焦点 |
+| focus() | 获取焦点 |
+
+## 设计变量
+<DesignToken/>

+ 407 - 0
content/input/radio/index-en-US.md

@@ -0,0 +1,407 @@
+---
+localeCode: en-US
+order: 23
+category: Input
+title: Radio
+subTitle: Radio
+icon: doc-radio
+brief: Radio component allows the user to select one option from a relative small set.
+---
+
+## When to use
+
+-   Used to select a single state among multiple options.
+-   The difference from Select is that all available options in Radio are visible by default, making it easier for users to choose in comparison, so there should not be too many options.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Radio, RadioGroup } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <Radio>Radio</Radio>
+)
+
+```
+
+### Extra Info
+
+You can use `extra` to add extra information, which can be any type of ReactNode.
+
+> `extra` >= v0.25.0
+
+```jsx live=true
+import React from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+
+() => (
+    <Radio extra="Semi Design is a design system developed and maintained by IES Front-end Team and UED Team">
+        Semi Design
+    </Radio>
+)
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { Radio, Button } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            disabled: true,
+        };
+        this.toggleDisabled = this.toggleDisabled.bind(this);
+    }
+
+    toggleDisabled() {
+        this.setState({
+            disabled: !this.state.disabled,
+        });
+    }
+
+    render() {
+        return (
+            <div>
+                <Radio defaultChecked={false} disabled={this.state.disabled}>
+                    Disabled
+                </Radio>
+                <br />
+                <Radio defaultChecked disabled={this.state.disabled}>
+                    Disabled
+                </Radio>
+                <div style={{ marginTop: 20 }}>
+                    <Button type="primary" onClick={this.toggleDisabled}>
+                        Toggle disabled
+                    </Button>
+                </div>
+            </div>
+        );
+    }
+}
+```
+
+### Advanced Mode
+
+You can set `mode='advanced'` to allow options be able to unchecked when clicked again.
+
+```jsx live=true
+import React from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            checked: true,
+        };
+        this.onChange = this.onChange.bind(this);
+    }
+
+    onChange(e) {
+        console.log('radio checked', e.target.checked);
+        this.setState({
+            checked: e.target.checked,
+        });
+    }
+
+    render() {
+        return (
+            <div>
+                <Radio checked={this.state.checked} mode="advanced" onChange={this.onChange}>
+                    Click Again to Uncheck
+                </Radio>
+            </div>
+        );
+    }
+}
+```
+
+### Mutually Exclusive Set
+
+You can use `RadioGroup` to create a set of mutually exclusive options.
+
+```jsx live=true
+import React from 'react';
+import { Radio, RadioGroup } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value: 1,
+        };
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(e) {
+        console.log('radio checked', e.target.value);
+        this.setState({
+            value: e.target.value,
+        });
+    }
+
+    render() {
+        return (
+            <RadioGroup onChange={this.onChange} value={this.state.value}>
+                <Radio value={1}>A</Radio>
+                <Radio value={2}>B</Radio>
+                <Radio value={3}>C</Radio>
+                <Radio value={4}>D</Radio>
+            </RadioGroup>
+        );
+    }
+}
+```
+
+### Button Style
+
+version: >=1.26.0
+
+You can use `type='button'` to set the button style type radio, and the button type radio supports three sizes.
+
+It should be noted that the button type radio selector does not support auxiliary text (`extra`) and vertical arrangement (`direction='vertical'`).
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Radio, RadioGroup, Space } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value1: 1,
+            value2: 1,
+            value3: 1,
+        };
+        this.onChange1 = this.onChange1.bind(this);
+        this.onChange2 = this.onChange2.bind(this);
+        this.onChange3 = this.onChange3.bind(this);
+    }
+
+    onChange1(e) {
+        this.setState({
+            value1: e.target.value,
+        });
+    }
+
+    onChange2(e) {
+        this.setState({
+            value2: e.target.value,
+        });
+    }
+
+    onChange3(e) {
+        this.setState({
+            value3: e.target.value,
+        });
+    }
+
+    render() {
+        return (
+            <Space vertical spacing="loose" align="start">
+                <RadioGroup type="button" buttonSize="small" onChange={this.onChange1} value={this.state.value1}>
+                    <Radio value={1}>Instant push</Radio>
+                    <Radio value={2}>Timed push</Radio>
+                    <Radio value={3}>Dynamic push</Radio>
+                </RadioGroup>
+                <RadioGroup type="button" buttonSize="middle" onChange={this.onChange2} value={this.state.value2}>
+                    <Radio value={1}>Instant push</Radio>
+                    <Radio value={2}>Timed push</Radio>
+                    <Radio value={3}>Dynamic push</Radio>
+                </RadioGroup>
+                <RadioGroup type="button" buttonSize="large" onChange={this.onChange3} value={this.state.value3}>
+                    <Radio value={1}>Instant push</Radio>
+                    <Radio value={2}>Timed push</Radio>
+                    <Radio value={3}>Dynamic push</Radio>
+                </RadioGroup>
+            </Space>
+        );
+    }
+}
+```
+
+### Card Style
+
+version: >=1.30.0
+
+You can set `type='card'` to `RadioGroup` to achieve card style with background.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <RadioGroup type='card' defaultValue={1} direction='vertical'>
+        <Radio value={1} extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+        <Radio value={2} disabled extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+        <Radio value={3} extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+    </RadioGroup>
+);
+```
+
+
+### Pure Card Style
+
+version: >=1.30.0
+
+You can set `type='pureCard'` to `RadioGroup` to achieve a pure card style with background and no radio.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <RadioGroup type='pureCard' defaultValue={1} direction='vertical'>
+        <Radio value={1} extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+        <Radio value={2} disabled extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+        <Radio value={3} extra='Radio description' style={{width:280}}>
+            Radio Title
+        </Radio>
+    </RadioGroup>
+);
+```
+
+### Options Configuration
+
+You can pass an array of options to `RadioGroup` using `options` property to create a set.
+
+```jsx live=true
+import React from 'react';
+import { RadioGroup } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value1: 'Guest',
+            value2: 'Developer',
+            value3: 'Maintainer',
+        };
+        this.plainOptions = ['Guest', 'Developer', 'Maintainer'];
+        this.options = [
+            { label: 'Guest', value: 'Guest', extra: 'Semi Design', style: { width: 120 } },
+            { label: 'Developer', value: 'Developer', extra: 'Semi Design', style: { width: 120 } },
+            { label: 'Maintainer', value: 'Maintainer', extra: 'Semi Design', style: { width: 120 } },
+        ];
+        this.optionsWithDisabled = [
+            { label: 'Guest', value: 'Guest' },
+            { label: 'Developer', value: 'Developer' },
+            { label: 'Maintainer', value: 'Maintainer', disabled: true },
+        ];
+        this.onChange1 = this.onChange1.bind(this);
+        this.onChange2 = this.onChange2.bind(this);
+        this.onChange3 = this.onChange3.bind(this);
+    }
+    onChange1(e) {
+        console.log('radio1 checked', e.target.value);
+        this.setState({
+            value1: e.target.value,
+        });
+    }
+
+    onChange2(e) {
+        console.log('radio2 checked', e.target.value);
+        this.setState({
+            value2: e.target.value,
+        });
+    }
+
+    onChange3(e) {
+        console.log('radio3 checked', e.target.value);
+        this.setState({
+            value3: e.target.value,
+        });
+    }
+
+    render() {
+        return (
+            <div>
+                <RadioGroup options={this.plainOptions} onChange={this.onChange1} value={this.state.value1} />
+                <br />
+                <br />
+                <RadioGroup options={this.optionsWithDisabled} onChange={this.onChange3} value={this.state.value3} />
+                <br />
+                <br />
+                <RadioGroup options={this.options} onChange={this.onChange2} value={this.state.value2} />
+            </div>
+        );
+    }
+}
+```
+
+## API Reference
+
+### Radio
+
+| PROPERTIES | Instructions | Type | Default |
+| --- | --- | --- | --- |
+| addonClassName | classname of content wrapper<br/>**provided after v1.16.0** | string |  |
+| addonStyle | inline style of content wrapper<br/>**provided after v1.16.0** | object |  |
+| autoFocus | Automatically focus the form control when the page is loaded | boolean | false |
+| checked | Specify whether it is currently selected | boolean | false |
+| className | Class name | string |  |
+| defaultChecked | Checked by default | boolean | false |
+| disabled | Disable the radio | boolean | false |
+| extra | Extra information displayed <br/>**provided after v0.25.0** | reactNode | - |
+| mode | In advanced mode, options can be clicked to uncheck, one of `advanced` | string | - |
+| style | Inline style | CSSProperties |  |
+| value | Compared based on value to determine whether the option is selected | any | - |
+| onChange | Callback function when the selected option changes | Function (e: Event) | - |
+| onMouseEnter | The callback function when the mouse moves into the option   | function(e:Event) | -   |
+| onMouseLeave | The callback function when the mouse moves out the option   | function(e:Event) | -   |
+### RadioGroup
+
+| PROPERTIES | Instructions | Type | Default |
+| --- | --- | --- | --- |
+| buttonSize | The size of the button type radio, one of `small`、`middle`、`large` <br/>**Provided after v1.26.0** | string | `middle` |
+| className | Class name | string |  |
+| defaultValue | Options selected by default | any | - |
+| direction | Arrangement direction of Radio, optional 'horizontal' / 'vertical', <br/>**provided after v0.31.0** | string | 'horizontal' |
+| disabled | Disable the entire group | boolean | false |
+| mode | In advanced mode, options can be clicked to uncheck, one of `advanced`<br/>**provided after v1.9.0** | string | - |
+| name | The `name` attribute for all `input[type="radio"]` in RadioGroup | string | - |
+| options | Set child options through configuration | Array | - |
+| style | Inline style | CSSProperties |  |
+| value | Used to set the currently selected value | any | - |
+| type | Set the type of radio, one of `default`, `button`, `card`, `pureCard` <br/>**This api is provided after v1.26.0, and card and pureCard are in v1.30.0 Provided after ** | string | `default` |
+| onChange | Callback function when the selected option changes | Function (e: Event) | - |
+## Method
+
+### Radio
+
+| Name    | Description  |
+| ------- | ------------ |
+| blur()  | Remove focus |
+| focus() | Get focus    |
+
+<!-- ## Related Material
+
+```material
+123
+``` -->
+
+## Design Tokens
+
+<DesignToken/>

+ 364 - 0
content/input/radio/index.md

@@ -0,0 +1,364 @@
+---
+localeCode: zh-CN
+order: 23
+category: 输入类
+title: Radio 单选框
+icon: doc-radio
+brief: 用户使用单选框来从少量的选项集合中选择单个选项
+---
+
+## 何时使用
+
+-   用于在多个备选项中选中单个状态。
+-   和 Select 的区别是,Radio 所有选项默认可见,方便用户在比较中选择,因此选项不宜过多。
+
+## 代码演示
+### 如何引入
+
+```jsx import
+import { Radio, RadioGroup } from '@douyinfe/semi-ui';
+```
+### 基本用法
+
+```jsx live=true
+import React from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <Radio>Radio</Radio>
+)
+```
+
+### 带辅助文本
+
+通过`extra`设置辅助文本,可以是任意类型的 ReactNode
+
+> `extra`在 v0.25.0 后开始提供
+
+```jsx live=true
+import React from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <Radio extra="Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统">
+        Semi Design
+    </Radio>
+)
+```
+
+### 禁用
+
+Radio 不可用
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Radio, Button } from '@douyinfe/semi-ui';
+
+() => {
+    const [disabled, setDisabled] = useState(true);
+    const toggleDisabled = () => {
+        setDisabled(!disabled);
+    };
+    return (
+        <div>
+            <Radio defaultChecked={false} disabled={disabled}>
+                Disabled
+            </Radio>
+            <br />
+            <Radio defaultChecked disabled={disabled}>
+                Disabled
+            </Radio>
+            <div style={{ marginTop: 20 }}>
+                <Button type="primary" onClick={toggleDisabled}>
+                    Toggle disabled
+                </Button>
+            </div>
+        </div>
+    )
+}
+```
+
+### 高级模式
+
+高级模式(mode='advanced')checked 可以通过点击转换为 unchecked。
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Radio } from '@douyinfe/semi-ui';
+
+() => {
+    const [checked, setChecked] = useState(true);
+    const toggle = (e) => {
+        console.log('radio checked', e.target.checked);
+        setChecked(e.target.checked);
+    };
+    return (
+        <Radio 
+            checked={checked}
+            mode="advanced"
+            onChange={toggle}
+        >
+            允许取消选择
+        </Radio>
+    )
+}
+```
+
+### 单选组合
+
+一组互斥的 Radio 配合使用
+
+```jsx live=true
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => {
+    const [value,  setValue] = useState(1);
+    const onChange = (e) => {
+        console.log('radio checked', e.target.value);
+        setValue(e.target.value);
+    } 
+    return (
+        <RadioGroup onChange={onChange} value={value}>
+            <Radio value={1}>A</Radio>
+            <Radio value={2}>B</Radio>
+            <Radio value={3}>C</Radio>
+            <Radio value={4}>D</Radio>
+        </RadioGroup>
+    );
+}
+```
+
+### 垂直排列
+
+可通过给 RadioGroup 设置 `direction`属性来决定 组内的 radio 元素水平排列或者垂直排列
+
+```jsx live=true
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <RadioGroup direction="vertical">
+        <Radio value={1}>A</Radio>
+        <Radio value={2}>B</Radio>
+        <Radio value={3}>C</Radio>
+        <Radio value={4}>D</Radio>
+    </RadioGroup>
+)
+```
+
+### 按钮样式
+
+version: >=1.26.0
+
+可以利用 `type='button'` 来设置 button 样式类型的单选器,并且,button 类型单选器支持三种尺寸大小。
+
+需要注意的是: button 类型的单选器暂不支持辅助文本(`extra`)和垂直排列(`direction='vertical'`)。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { RadioGroup, Radio, Space } from '@douyinfe/semi-ui';
+
+() => {
+    return (
+        <Space vertical spacing='loose' align='start'>
+            <RadioGroup type='button' buttonSize='small' defaultValue={1}>
+                <Radio value={1}>即时推送</Radio>
+                <Radio value={2}>定时推送</Radio>
+                <Radio value={3}>动态推送</Radio>
+            </RadioGroup>
+            <RadioGroup type='button' buttonSize='middle' defaultValue={1}>
+                <Radio value={1}>即时推送</Radio>
+                <Radio value={2}>定时推送</Radio>
+                <Radio value={3}>动态推送</Radio>
+            </RadioGroup>
+            <RadioGroup type='button' buttonSize='large' defaultValue={1}>
+                <Radio value={1}>即时推送</Radio>
+                <Radio value={2}>定时推送</Radio>
+                <Radio value={3}>动态推送</Radio>
+            </RadioGroup>
+        </Space>
+    )
+}
+```
+
+### 卡片样式
+
+version: >=1.30.0
+
+可以给 `RadioGroup` 设置 `type='card'` 实现带有背景的卡片样式。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <RadioGroup type='card' defaultValue={2} direction='vertical'>
+        <Radio value={1} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+        <Radio value={2} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+        <Radio value={3} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+    </RadioGroup>
+);
+```
+### 无 radio 的纯卡片样式
+
+version: >=1.30.0
+
+可以给 `RadioGroup` 设置 `type='pureCard'` 实现带有背景且无 radio 的纯卡片样式。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { RadioGroup, Radio } from '@douyinfe/semi-ui';
+
+() => (
+    <RadioGroup type='pureCard' defaultValue={2} direction='vertical'>
+        <Radio value={1} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+        <Radio value={2} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+        <Radio value={3} extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{width:280}}>
+            单选框标题
+        </Radio>
+    </RadioGroup>
+);
+```
+
+### 配置 options
+
+通过配置 options 参数来渲染单选框
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { RadioGroup, Space } from '@douyinfe/semi-ui';
+
+class App extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value1: 'Guest',
+            value2: 'Developer',
+            value3: 'Maintainer',
+        };
+        this.plainOptions = ['Guest', 'Developer', 'Maintainer'];
+        this.options = [
+            { label: 'Guest', value: 'Guest', extra: 'Semi Design', style: { width: 120 } },
+            { label: 'Developer', value: 'Developer', extra: 'Semi Design', style: { width: 120 } },
+            { label: 'Maintainer', value: 'Maintainer', extra: 'Semi Design', style: { width: 120 } },
+        ];
+        this.optionsWithDisabled = [
+            { label: 'Guest', value: 'Guest' },
+            { label: 'Developer', value: 'Developer' },
+            { label: 'Maintainer', value: 'Maintainer', disabled: true },
+        ];
+        this.onChange1 = this.onChange1.bind(this);
+        this.onChange2 = this.onChange2.bind(this);
+        this.onChange3 = this.onChange3.bind(this);
+    }
+    onChange1(e) {
+        console.log('radio1 checked', e.target.value);
+        this.setState({
+            value1: e.target.value,
+        });
+    }
+
+    onChange2(e) {
+        console.log('radio2 checked', e.target.value);
+        this.setState({
+            value2: e.target.value,
+        });
+    }
+
+    onChange3(e) {
+        console.log('radio3 checked', e.target.value);
+        this.setState({
+            value3: e.target.value,
+        });
+    }
+
+    render() {
+        return (
+            <Space vertical align='start' spacing='loose'>
+                <RadioGroup
+                    options={this.plainOptions}
+                    onChange={this.onChange1}
+                    value={this.state.value1}
+                />
+                <RadioGroup
+                    options={this.optionsWithDisabled}
+                    onChange={this.onChange3}
+                    value={this.state.value3}
+                />
+                <RadioGroup
+                    options={this.options}
+                    onChange={this.onChange2}
+                    value={this.state.value2}
+                />
+            </Space>
+        );
+    }
+}
+```
+
+## API 参考
+
+### Radio
+
+| 属性           | 说明                                                                   | 类型              | 默认值  |
+|----------------|-----------------------------------------------------------------------|------------------|--------|
+| addonClassName | 包裹内容容器的样式类名  **v1.16.0 后提供**                                 | string            |       |
+| addonStyle     | 包裹内容容器的内联样式  **v1.16.0 后提供**                                 | CSSProperties     |       |
+| autoFocus      | 自动获取焦点                                                            | boolean           | false  |
+| checked        | 指定当前是否选中                                                         | boolean           | false  |
+| className      | 样式类名                                                                | string            |        |
+| defaultChecked | 初始是否选中                                                             | boolean           | false  |
+| disabled       | 禁选单选框                                                              |boolean            | false    |
+| extra          | 副文本,只对type='default'生效<br/>**v0.25.0 后提供**                     | reactNode         | -      |
+| mode           | 高级和普通模式,高级模式可以在 checked 时点击变成 unchecked,可选值 advanced   | string            | -      |
+| style          | 内联样式                                                                 | CSSProperties    |        |
+| value          | 根据 value 进行比较,判断是否选中                                          | any               | -      |
+| onChange       | 选项变化时的回调函数                                                      | function(e:Event) | -      |
+| onMouseEnter   | 鼠标移入选项时的回调函数                                                   | function(e:Event) | -      |
+| onMouseLeave   | 鼠标移出选项时的回调函数                                                   | function(e:Event) | -      |
+### RadioGroup
+
+单选框组合,用于包裹一组 `Radio`。
+
+| 属性         | 说明                                                                                        | 类型                                                                      | 默认值       |
+| ------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------ |
+|buttonSize|type='button'的radio的尺寸大小,可选值为:`small`、`middle`、`large` <br/>**v1.26.0 后提供** |string|`middle`|
+| className    | 样式类名                                                                                    | string                                                                    |              |
+| defaultValue | 默认选中的值                                                                                | any                                                                       | -            |
+| direction    | radio 排列方向, 只对type='default'生效,可选值`horizontal`、`vertical` <br/>**v0.31.0 后提供**                      | string                                                                    | `horizontal` |
+| disabled     | 禁选所有子单选器                                                                            | boolean                                                                   | false        |
+| mode         | 高级和普通模式,可以在 checked 时点击变成 unchecked,可选值 advanced <br/>**v1.9.0 后提供** | string                                                                    | -            |
+| name         | RadioGroup 下所有 `input[type="radio"]` 的 `name` 属性                                      | string                                                                    | -            |
+| options      | 以配置形式设置子元素                                                                        | Array | -            |
+| style        | 内联样式                                                                                    | CSSProperties                                                                    |              |
+| value        | 用于设置当前选中的值                                                                        | any                                                                       | -            |
+|type|设置所有radio的样式类型,可选值为:`default`、`button`、`card`、`pureCard` <br/>**该 api 在 v1.26.0 后提供,其中 card 和 pureCard 在 v1.30.0 后提供**    |string|`default`|
+| onChange     | 选项变化时的回调函数                                                                        | function(e:Event)                                                         | -            |
+
+## 方法
+
+### Radio
+
+| 名称    | 描述     |
+| ------- | -------- |
+| blur()  | 移除焦点 |
+| focus() | 获取焦点 |
+
+<!-- ## 相关物料
+```material
+123
+``` -->
+
+## 设计变量
+<DesignToken/>

+ 182 - 0
content/input/rating/index-en-US.md

@@ -0,0 +1,182 @@
+---
+localeCode: en-US
+order: 24
+category: Input
+title: Rating
+subTitle: Rating
+icon: doc-rating
+brief: Ratings provide insight regarding others’ opinions and experiences with a product.
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Rating } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+Support two sizes: `default`, `small`.
+
+**v >= 0.35.0** supports customized size if pass in a number. Refer to [Customize](#Customize)
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Rating Default Value={5} />
+        <br />
+        <br />
+        <Rating size="small" defaultValue={5} />
+    </div>
+)
+```
+
+### Half Star
+
+Use `allowHalf` to support selection of half stars. After `v0.28.0`, it also supports to **display** decimals ratings other than 0.5.
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Rating allowHalf defaultValue={3.5} />
+        <br />
+        <Rating allowHalf defaultValue={3.65} />
+    </div>
+)
+```
+
+### Disabled
+
+Use `disabled` to disabled interaction.
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <Rating disabled defaultValue={3} />
+)
+```
+
+### Click to Clear
+
+`allowClear` Property allows you to clear the value when you click on the component again. By default it is set to `true`.
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <span>Clear when clicking</span>
+        <br />
+        <Rating allowClear={true} defaultValue={3} />
+        <br />
+        <br />
+        <span>Unable to clear when clicking</span>
+        <br />
+        <Rating allowClear={false} defaultValue={3} />
+    </div>
+)
+```
+
+### Text Description
+
+Use `tooltips` to add description to Rating.
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor(props) {
+        super();
+        this.state = { value: 0 };
+        this.handleChange = this.handleChange.bind(this);
+    }
+
+    handleChange(value) {
+        this.setState({ value });
+    }
+
+    render() {
+        const { value } = this.state;
+        const desc = ['terrible', 'bad', 'normal', 'good', 'wonderful'];
+        return (
+            <div>
+                <span>
+                    How was the help you received:
+                    {value ? <span>{desc[value - 1]}</span> : ''}
+                </span>
+                <br />
+                <Rating tooltips={desc} onChange={this.handleChange} value={value} />
+            </div>
+        );
+    }
+}
+```
+
+### Customize
+
+You can customize characters, numbers of rating and size.
+
+> **v >= 0.35.0** Note that customized size could only work with customized characters.
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+import { IconLikeHeart } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Rating style={{ color: 'red' }} character={<IconLikeHeart size="extra-large" />} defaultValue={3} />
+        <br />
+        <br />
+        <Rating
+            style={{ color: 'red' }}
+            size={48}
+            allowHalf
+            character={<IconLikeHeart style={{ fontSize: 48 }} />}
+            defaultValue={3}
+        />
+        <br />
+        <br />
+        <Rating size={18} character={'S'} defaultValue={3} />
+        <br />
+        <br />
+        <Rating Count={10} defaultValue={6} />
+    </div>
+)
+```
+
+## API Reference
+
+| Properties    | Instructions                                                                          | type                    | Default                                  |
+| ------------- | ------------------------------------------------------------------------------------- | ----------------------- | ---------------------------------------- |
+| allowClear    | Toggle whether it is allowed to clear when clicking                                   | boolean                 | true                                     |
+| allowHalf     | Toggle whether it is allowed to select half stars                                     | boolean                 | false                                    |
+| autoFocus     | Automaticly focus                                                                     | boolean                 | false                                    |
+| character     | Custom characters to display rating                                                   | React Node              | `<IconStar size="extra-large"/>` |
+| className     | Class name                                                                            | string                  | -                                        |
+| count         | Number of stars or characters                                                         | number                  | 5                                        |
+| defaultValue  | Default value                                                                         | number                  | 0                                        |
+| disabled      | Read-only, disable interaction.                                                       | boolean                 | false                                    |
+| onBlur        | Callback function when losing focus.                                                  | function()              | -                                        |
+| onChange      | Callback function at the time of selection                                            | function(value: number) | -                                        |
+| onFocus       | Callback function when getting focus                                                  | function()              | -                                        |
+| onHoverChange | Callback function of numerical changes when the mouse hovers                          | function(value: number) | -                                        |
+| onKeyDown     | Callback function when key down                                                       | function(e: event)      | -                                        |
+| size          | Size, one of `default`, `small`, **v >= 0.35.0** could use number for customized size | string\| number         | `default`                                |
+| style         | Inline style                                                                          | object                  | -                                        |
+| tooltips      | Customize prompted information for each item                                          | String[]                | -                                        |
+| value         | Controlled value                                                                      | number                  | -                                        |
+
+## Design Tokens
+<DesignToken/>

+ 159 - 0
content/input/rating/index.md

@@ -0,0 +1,159 @@
+---
+localeCode: zh-CN
+order: 24
+category: 输入类
+title:  Rating 评分
+icon: doc-rating
+brief: 展示评分的组件。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Rating } from '@douyinfe/semi-ui';
+```
+### 基本用法
+
+最简单的用法,支持两种尺寸 `default`, `small`。  
+
+**v >= 0.35.0** 后支持传入 number 类型自定义尺寸。具体可以参考[自定义](#自定义)
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Rating defaultValue={5}/>
+        <br/>
+        <br/>
+        <Rating size='small' defaultValue={5}/>
+    </div>
+)
+```
+
+### 半星
+
+通过设置 `allowHalf` 属性可以支持选择半星。`0.28.0` 版本之后,设置 `allowHalf` 属性支持**展示**除0.5以外的小数。
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Rating allowHalf defaultValue={3.5}/>
+        <br/>
+        <Rating allowHalf defaultValue={3.65}/>
+    </div>
+)
+```
+
+### 只读
+通过设置 `disabled` 属性将无法进行交互。
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <Rating disabled defaultValue={3} />
+)
+```
+
+### 点击清除
+通过设置 `allowClear` 属性允许再次点击时清除数值,默认为 `true`。
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <span>允许再次点击清除</span>
+        <br/>
+        <Rating allowClear={true} defaultValue={3}/>
+        <br/>
+        <br/>
+        <span>禁止再次点击清除</span>
+        <br/>
+        <Rating allowClear={false} defaultValue={3}/>
+    </div>
+)
+```
+
+### 文案展现
+
+给评分组件加上文案展示。
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+
+() => {
+    const [value,  setValue] = useState(0);
+    const change = (val) => setValue(val);
+    const desc = ['terrible', 'bad', 'normal', 'good', 'wonderful'];
+    return (
+        <div>
+            <span>How was the help you received: 
+                {value ? <span>{desc[value - 1]}</span> : ''}
+            </span>
+            <br/>
+            <Rating tooltips={desc} onChange={change} value={value} />
+        </div>
+    );
+}
+```
+
+### 自定义
+
+自定义评分字符、个数及尺寸。  
+> **v >= 0.35.0** 自定义尺寸需要配合自定义的字符才能生效。
+
+```jsx live=true
+import React from 'react';
+import { Rating } from '@douyinfe/semi-ui';
+import { IconLikeHeart } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Rating style={{color:'red'}} character={(<IconLikeHeart size="extra-large" />)} defaultValue={3}/>
+        <br/>
+        <br/>
+        <Rating style={{color:'red'}} size={48} allowHalf character={(<IconLikeHeart style={{ fontSize: 48 }} />)} defaultValue={3}/>
+        <br/>
+        <br/>
+        <Rating character={'赞'} size={18} defaultValue={3}/>
+        <br/>
+        <br/>
+        <Rating count={10} defaultValue={6}/>
+    </div>
+)
+```
+
+## API参考
+
+| 属性  | 说明        | 类型            | 默认值 |
+|-------|-------------|-----------------|--------|
+| allowClear | 是否允许再次点击后清除 | boolean | true |
+| allowHalf | 是否允许半选 | boolean | false |
+| autoFocus | 自动获取焦点 | boolean | false |
+| character | 自定义字符 | ReactNode | `<IconStar size="extra-large"/>` |
+| className | 自定义样式类名 | string | - |
+| count | star 总数 | number | 5 |
+| defaultValue | 默认值 | number | 0 |
+| disabled | 只读,无法进行交互 | boolean | false |
+| onBlur | 失去焦点时的回调 | function() | - |
+| onChange | 选择时的回调 | function(value: number) | - |
+| onFocus | 获取焦点时的回调 | function() | - |
+| onHoverChange | 鼠标经过时数值变化的回调 | function(value: number) | - |
+| onKeyDown | 按键回调 | function(e: event) | - |
+| size | 尺寸, `default`, `small`,**v >= 0.35.0** 后支持传入 number 类型自定义尺寸 | string \| number | `default` |
+| style | 自定义样式对象 | object | - |
+| tooltips | 自定义每项的提示信息 | string[] | - |
+| value | 当前受控值 | number | - |
+
+## 设计变量
+<DesignToken/>

+ 1415 - 0
content/input/select/index-en-US.md

@@ -0,0 +1,1415 @@
+---
+localeCode: en-US
+order: 25
+category: Input
+title: Select
+subTitle: Select
+icon: doc-select
+width: 60%
+brief: The user can select one or more options from a set of options through the Select selector and present the final selection result
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Select } from '@douyinfe/semi-ui';
+const Option = Select.Option;
+```
+
+### Basic Usage
+
+Each Option tag must declare the `value` attribute, and the Option `children` content will be rendered to the drop-down list
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <Select defaultValue="tiktok" style={{ width: 120 }}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select style={{ width: '180px' }} defaultValue="tiktok" style={{ width: 120 }}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select placeholder="Select line of business" style={{ width: 120 }}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+    </>
+)
+```
+
+### Pass Option as an array
+
+You can pass an array of objects directly through `optionList`. Each object must contain the value / label attribute.
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    const list = [
+        { value: 'tiktok', label: 'Tiktok' },
+        { value: 'hotsoon', label: 'Hotsoon' },
+        { value: 'pipixia', label: 'Pipixia' },
+        { value: 'toutiao', label: 'TooBuzz' },
+    ];
+    return <Select placeholder="Business line" style={{ width: 180 }} optionList={list}></Select>;
+};
+```
+
+### Multi-choice
+
+Configuration `multiple` properties that can support multi-selection
+
+Configuration `maxTagCount`. You can limit the number of options displayed, and the excess will be displayed in the form of + N
+
+Configuration `max` Properties can limit the maximum number of options and cannot be selected beyond the maximum limit, while triggering`On Exceed`callback
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <Select multiple style={{ width: '320px' }} defaultValue={['tiktok', 'hotsoon']}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+            <Select.Option value="pipixia">Pipixia</Select.Option>
+            <Select.Option value="xigua">BuzzVideo</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select multiple style={{ width: '320px' }} defaultValue={['tiktok', 'hotsoon', 'pipixia']} maxTagCount={2}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+            <Select.Option value="pipixia">Pipixia</Select.Option>
+            <Select.Option value="xigua">BuzzVideo</Select.Option>
+        </Select>
+
+        <br />
+        <br />
+        <Select
+            multiple
+            style={{ width: '320px' }}
+            defaultValue={['tiktok']}
+            max={2}
+            onExceed={() => Toast.warning('Only two options are allowed')}
+        >
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+            <Select.Option value="pipixia">Pipixia</Select.Option>
+            <Select.Option value="xigua">BuzzVideo</Select.Option>
+        </Select>
+    </>
+)
+```
+### With Group
+
+Grouping Option with `OptGroup`(Only supports the declaration of children through jsx, and does not support pass in through optionList)
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <Select placeholder="" style={{ width: 180 }} filter>
+        <Select.OptGroup label="Asia">
+            <Select.Option value="a-1">China</Select.Option>
+            <Select.Option value="a-2">Koera</Select.Option>
+        </Select.OptGroup>
+        <Select.OptGroup label="Europe">
+            <Select.Option value="b-1">Germany</Select.Option>
+            <Select.Option value="b-2">France</Select.Option>
+        </Select.OptGroup>
+        <Select.OptGroup label="South America">
+            <Select.Option value="c-1">Peru</Select.Option>
+        </Select.OptGroup>
+    </Select>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    const data = [
+        {
+            label: 'Asia',
+            children: [
+                { value: 'a-1', label: 'China' },
+                { value: 'a-2', label: 'Koera' },
+            ],
+        },
+        {
+            label: 'Europe',
+            children: [
+                { value: 'b-1', label: 'Germany' },
+                { value: 'b-2', label: 'France' },
+            ],
+        },
+        {
+            label: 'South America',
+            children: [{ value: 'c-1', label: 'Peru' }],
+        },
+    ];
+    return (
+        <Select placeholder="" style={{ width: 180 }} filter>
+            {data.map(group => (
+                <Select.OptGroup label={group.label} key={group.label}>
+                    {group.children.map(option => (
+                        <Select.Option key={option.value} value={option.value}>
+                            {option.label}
+                        </Select.Option>
+                    ))}
+                </Select.OptGroup>
+            ))}
+        </Select>
+    );
+};
+```
+
+### Different sizes
+
+Size: small / default / large
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <Select placeholder="Business line" style={{ width: '200px' }} size="small">
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select placeholder="Business line" style={{ width: '200px' }}>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select placeholder="Business line" style={{ width: '200px' }} size="large">
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        </Select>
+    </>
+)
+```
+
+### Different validate status
+
+validateStatus: default / warning / error
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <Select style={{ width: '180px' }}>
+            <Select.Option value="Capcut">Capcut</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select style={{ width: '180px' }} validateStatus="warning">
+            <Select.Option value="Capcut">Capcut</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select style={{ width: '180px' }} validateStatus="error">
+            <Select.Option value="Capcut">Capcut</Select.Option>
+        </Select>
+    </>
+)
+```
+
+### Configure Prefix, Suffix, Clear Button
+
+-   You can pass the selection box prefix through `prefix`, the selection box suffix through `suffix`, for text or React Node  
+    The left and right padding is automatically brought when the content passed in by prefix and reactix is text or Icon. If it is a custom ReactNode, the left and right padding is 0.
+-   Whether to show the clear button is displayed by `showClear`
+-   Whether to show the right drop-down arrow is displayed by `showArrow`
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
+
+() => (
+    <>
+        <Select style={{ width: '320px' }} defaultValue={'hotsoon'} prefix={<IconVigoLogo />} showClear={true}>
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+            <Select.Option value="pipixia">Pipixia</Select.Option>
+            <Select.Option value="xigua">BuzzVideo</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select
+            style={{ width: '320px' }}
+            defaultValue={'hotsoon'}
+            prefix={<IconVigoLogo />}
+            suffix={<IconGift />}
+            showArrow={false}
+        >
+            <Select.Option value="tiktok">Tiktok</Select.Option>
+            <Select.Option value="hotsoon">Hotsoon</Select.Option>
+            <Select.Option value="pipixia">Pipixia</Select.Option>
+            <Select.Option value="xigua">BuzzVideo</Select.Option>
+        </Select>
+    </>
+)
+```
+
+### Select with inset label
+
+By setting`insetLabel`, you can set a label for Select, you can pass in string or ReactNode  
+When the incoming type is ReactNode, you need to handle the padding between the label and the text.
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    const list = [
+        { value: 'tiktok', label: 'Tiktok' },
+        { value: 'capcut', label: 'Capcut' },
+        { value: 'xigua', label: 'BuzzVideo' },
+    ];
+    return (
+        <>
+            <Select style={{ width: 320 }} optionList={list} insetLabel="Application" defaultValue="tiktok"></Select>
+            <br />
+            <br />
+            <Select
+                style={{ width: 320 }}
+                optionList={list}
+                insetLabel={
+                    <span style={{ marginRight: 0, marginLeft: 12, color: 'var(--semi-color-text-2)' }}>
+                        Application
+                    </span>
+                }
+            ></Select>
+        </>
+    );
+};
+```
+
+### Additional items
+
+We have reserved two slots at the bottom of the pop-up layer, which you can use when you need to add a custom node to the pop-up layer.  
+Use`innerTopSlot` or `outerTopSlot` to pass the custom node, which will be rendered at the top of the pop-up layer. Use`innerBottomSlot` or `outerBottomSlot` instead at the bottom.
+
+-   `innerTopSlot` and `innerBottomSlot` will be rendered inside the Option List
+
+-   `outerTopSlot` and `outerBottomSlot` will be rendered to level with the option List
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { IconClock } from '@douyinfe/semi-icons';
+
+() => {
+    let selectStyle = { width: 180, margin: 20 };
+    let innerSlotStyle = {
+        backgroundColor: '#FFF',
+        height: '40px',
+        color: '#0077FA',
+        display: 'flex',
+        justifyContent: 'center',
+        alignItems: 'center',
+        cursor: 'pointer',
+    };
+    let innerSlotNode = <div style={innerSlotStyle}>No suitable product?</div>;
+    let outSlotStyle = {
+        backgroundColor: 'whitesmoke',
+        height: '29px',
+        display: 'flex',
+        justifyContent: 'center',
+        alignItems: 'center',
+        cursor: 'pointer',
+    };
+    let outSlotNode = (
+        <div style={outSlotStyle}>
+            <IconClock></IconClock>
+            <span style={{ color: 'rgba(28, 31, 35, 0.55)' }}>More recently viewed pages</span>
+        </div>
+    );
+
+    return (
+        <div>
+            <p>outerBottomSlot:</p>
+            <Select
+                style={selectStyle}
+                dropdownStyle={{ width: 180 }}
+                maxHeight={213}
+                efaultOpen
+                autoAdjustOverflow={false}
+                position="bottom"
+                outerBottomSlot={outSlotNode}
+            >
+                <Select.Option value="tiktok">Tiktok</Select.Option>
+                <Select.Option value="hotsoon">Hotsoon</Select.Option>
+                <Select.Option value="pipixia">Pipixia</Select.Option>
+                <Select.Option value="xigua">BuzzVideo</Select.Option>
+            </Select>
+            <p>innerBottomSlot:</p>
+            <Select style={selectStyle} dropdownStyle={{ width: 180 }} innerBottomSlot={innerSlotNode}>
+                <Select.Option value="tiktok">Tiktok</Select.Option>
+                <Select.Option value="hotsoon">Hotsoon</Select.Option>
+                <Select.Option value="pipixia">Pipixia</Select.Option>
+                <Select.Option value="xigua">BuzzVideo</Select.Option>
+            </Select>
+        </div>
+    );
+};
+```
+
+Using outerTopSlot to insert content
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            key: 'component',
+        };
+        this.list = {
+            component: [
+                { value: 'select', label: 'Select' },
+                { value: 'tabs', label: 'Tabs' },
+                { value: 'avatar', label: 'Avatar' },
+                { value: 'button', label: 'Button' },
+            ],
+            design: [
+                { value: 'color', label: 'Color' },
+                { value: 'dark', label: 'Dark Mode' },
+                { value: 'icon', label: 'Icon' },
+                { value: 'font', label: 'Topography' },
+            ],
+            feedback: [
+                { value: 'faq', label: 'FAQ' },
+                { value: 'join', label: 'Join Chat Group' },
+                { value: 'hornbill', label: 'Hornbill' },
+            ],
+        };
+        this.handleTabClick = this.handleTabClick.bind(this);
+    }
+
+    handleTabClick(itemKey) {
+        this.setState({ key: itemKey });
+    }
+
+    render() {
+        const { key } = this.state;
+        const tabStyle = {
+            cursor: 'pointer',
+            marginRight: 12,
+            paddingBottom: 4,
+        };
+        const tabActiveStyle = {
+            ...tabStyle,
+            borderBottom: '1px solid var(--semi-color-primary)',
+            fontWeight: 700,
+        };
+        const tabWrapper = {
+            display: 'flex',
+            paddingTop: 8,
+            paddingLeft: 32,
+            borderBottom: '0.5px solid var(--semi-color-border)',
+        };
+        const tabOptions = [
+            { itemKey: 'component', label: 'Components' },
+            { itemKey: 'design', label: 'Design' },
+            { itemKey: 'feedback', label: 'Feedback' },
+        ];
+        const outerTopSlotNode = (
+            <div style={tabWrapper}>
+                {tabOptions.map((item, index) => {
+                    style = item.itemKey === key ? tabActiveStyle : tabStyle;
+                    return (
+                        <div style={style} key={item.itemKey} onClick={() => this.handleTabClick(item.itemKey)}>
+                            {item.label}
+                        </div>
+                    );
+                })}
+            </div>
+        );
+
+        return (
+            <div>
+                <Select
+                    style={{ width: 300 }}
+                    defaultOpen
+                    autoAdjustOverflow={false}
+                    position="bottom"
+                    outerTopSlot={outerTopSlotNode}
+                    optionList={this.list[key]}
+                />
+            </div>
+        );
+    }
+}
+```
+
+### Controlled component
+
+When `value` is passed, Select is a controlled component, and the value selected is entirely determined by `value`.
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    let [value, setValue] = useState('xigua');
+    return (
+        <>
+            <Select value={value} style={{ width: '300px' }} onChange={setValue} placeholder="Controlled Component">
+                <Select.Option value="tiktok">Tiktok</Select.Option>
+                <Select.Option value="capcut">Capcut</Select.Option>
+                <Select.Option value="xigua">BuzzVideo</Select.Option>
+            </Select>
+        </>
+    );
+};
+```
+
+### Linkage Select
+
+If it is a complex linkage with a hierarchical relationship, it is recommended to use Cascader components directly
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class Link extends React.Component {
+    get continents() {
+        return ['Asia', 'Europe'];
+    }
+    get maps() {
+        return {
+            Asia: ['China', 'Korea'],
+            Europe: ['United Kingdom', 'France', 'Germany'],
+        };
+    }
+    constructor() {
+        super();
+        this.state = {
+            continents: this.continents,
+            maps: this.maps,
+            countrys: this.maps[this.continents[0]],
+            country: this.maps[this.continents[0]][0],
+        };
+        this.continentsChange = this.continentsChange.bind(this);
+        this.countryChange = this.countryChange.bind(this);
+    }
+
+    continentsChange(newContinents) {
+        const { maps } = this.state;
+        this.setState({ countrys: maps[newContinents], country: maps[newContinents][0] });
+    }
+
+    countryChange(country) {
+        this.setState({ country });
+    }
+
+    render() {
+        const { continents, countrys, country } = this.state;
+        return (
+            <React.Fragment>
+                <Select
+                    style={{ width: '150px', margin: '10px' }}
+                    onChange={this.continentsChange}
+                    defaultValue={continents[0]}
+                >
+                    {continents.map(pro => (
+                        <Select.Option value={pro} key={pro}>
+                            {pro}
+                        </Select.Option>
+                    ))}
+                </Select>
+                <Select style={{ width: '150px', margin: '10px' }} value={country} onChange={this.countryChange}>
+                    {countrys.map(c => (
+                        <Select.Option value={c} key={c}>
+                            {c}
+                        </Select.Option>
+                    ))}
+                </Select>
+            </React.Fragment>
+        );
+    }
+}
+```
+
+### Search
+
+You can turn on the search capability by setting `filter` to true.  
+The default search strategy will include comparison of the input value with the label value of option
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <Select filter style={{ width: 180 }} placeholder="Searchable Select">
+            <Select.Option value="app1">Tiktok</Select.Option>
+            <Select.Option value="app2">Hotsoon</Select.Option>
+            <Select.Option value="app3">Pipixia</Select.Option>
+            <Select.Option value="app4">BuzzVideo</Select.Option>
+        </Select>
+        <br />
+        <br />
+        <Select filter multiple style={{ width: 350 }} placeholder="Searchable Multiple Select">
+            <Select.Option value="app1">Tiktok</Select.Option>
+            <Select.Option value="app2">Hotsoon</Select.Option>
+            <Select.Option value="app3">Pipixia</Select.Option>
+            <Select.Option value="app4">BuzzVideo</Select.Option>
+        </Select>
+    </>
+)
+```
+### Remote search
+
+A multi-select example with remote search, request debounce, loading status.
+
+-   Use `filter` turn on the search capability.
+-   Use `remote` to disbaled local filter
+-   Dynamic Update `optionList` after `onSearch` callback
+-   Update `loading` when fetching data / finish
+-   Use controlled value attribute
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { debounce } from 'lodash-es';
+
+class SearchDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            Loading: false,
+            optionList: [
+                { value: 'tiktok', label: 'Tiktok', type: 1 },
+                { value: 'capcut', label: 'Capcut', type: 2 },
+                { value: 'xigua', label: 'BuzzVideo', type: 4 },
+            ],
+            value: '',
+            multipleValue: [],
+        };
+        this.handleSearch = debounce(this.handleSearch, 800).bind(this);
+        this.onChange = this.onChange.bind(this);
+        this.onMultipleChange = this.onMultipleChange.bind(this);
+    }
+
+    handleSearch(inputValue) {
+        this.setState({ loading: true });
+        let length = Math.ceil(Math.random() * 100);
+        let result = Array.from({ length }, (v, i) => {
+            return { value: inputValue + i, label: inputValue + '-new line-' + i, type: i + 1 };
+        });
+        setTimeout(() => {
+            this.setState({ optionList: result, loading: false });
+        }, 2000);
+    }
+
+    onChange(value) {
+        this.setState({ value });
+    }
+
+    onMultipleChange(multipleValue) {
+        this.setState({ multipleValue });
+    }
+
+    render() {
+        const { loading, optionList, value, multipleValue } = this.state;
+        return (
+            <div>
+                <Select
+                    style={{ width: 300 }}
+                    filter
+                    remote
+                    onChangeWithObject
+                    onSearch={this.handleSearch}
+                    optionList={optionList}
+                    loading={loading}
+                    onChange={this.onChange}
+                    value={value}
+                    emptyContent={null}
+                ></Select>
+                <br />
+                <br />
+                <Select
+                    style={{ width: 300 }}
+                    filter
+                    remote
+                    onChangeWithObject
+                    multiple
+                    value={multipleValue}
+                    onSearch={this.handleSearch}
+                    optionList={optionList}
+                    loading={loading}
+                    onChange={this.onMultipleChange}
+                    placeholder="Multiple Select"
+                    emptyContent={null}
+                ></Select>
+            </div>
+        );
+    }
+}
+```
+### Custom search strategy
+
+By default, the user's search input will be compared with the option's label value as a string include.  
+You can set `filter` as a custom function to customize your filter strategy.
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    function search(sugInput, option) {
+        // Search for both label and value
+        let label = option.label.toUpperCase();
+        let value = option.value.toUpperCase();
+        let sug = sugInput.toUpperCase();
+        return label.includes(sug) || value.includes(sug);
+    }
+    return (
+        <Select filter={search} style={{ width: '180px' }} placeholder="try hello or tiktok">
+            <Select.Option value="hello">Tiktok</Select.Option>
+            <Select.Option value="bytedance">UlikeCam</Select.Option>
+            <Select.Option value="semi">BuzzVideo</Select.Option>
+        </Select>
+    );
+};
+```
+
+
+### Custom selection rendering
+
+By default, the content of `option.label` or `option.children` will be backfilled into the selection box when the option is selected.  
+But you can customize the rendering of the selection box through the `renderSelectedItem` function
+
+-   Select: `renderSelectedItem(optionNode: object) => content: ReactNode`
+-   Multiple Select: `renderSelectedItem(optionNode: object, { index: number, onClose: function }) => { isRenderInTag: boolean, content: ReactNode }`
+    -   When `isRenderInTag` is true, content will automatically wrapped in `Tag` rendering (with background color and close button)
+    -   When `isRenderInTag` is false, it renders the returned content directly
+
+```jsx live=true
+import React from 'react';
+import { Select, Avatar, Tag } from '@douyinfe/semi-ui';
+
+class CustomRender extends React.Component {
+
+    constructor() {
+        super();
+        this.state = {
+          list: [
+            { "name": "XiaKeMan", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"},
+            { "name": "ShenYue", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg"},
+            { "name": "QuChenYi", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg"},
+            { "name": "WenJiaMao", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png"},
+          ]
+        };
+    }
+
+    renderSelectedItem(optionNode) {
+        return (
+          <div key={optionNode.email} style={{display: 'flex', alignItems: 'center'}}>
+            <Avatar src={optionNode.avatar} size="small">{optionNode.abbr}</Avatar>
+            <span style={{ marginLeft: 8 }}>{optionNode.email}</span>
+          </div>
+        )
+    }
+
+    // avatarSrc & avatarShape are supported after 1.6.0
+    renderMultipleWithCustomTag(optionNode, { onClose }) {
+        let content = (
+            <Tag
+                avatarSrc={optionNode.avatar}
+                avatarShape='circle'
+                closable={true}
+                onClose={onClose}
+                size='large'
+                key={optionNode.name}
+                >
+                {optionNode.name}
+            </Tag>
+        );
+        return {
+          isRenderInTag: false,
+          content
+        };
+    }
+
+    renderMultipleWithCustomTag2(optionNode, { onClose }) {
+        let content = (
+            <Tag
+                avatarSrc={optionNode.avatar}
+                avatarShape='square'
+                closable={true}
+                onClose={onClose}
+                size='large'
+                key={optionNode.name}
+                >
+                {optionNode.name}
+            </Tag>
+        );
+        return {
+          isRenderInTag: false,
+          content
+        };
+    }
+
+    renderCustomOption(item) {
+        let optionStyle = {
+            display: 'flex',
+            paddingLeft: 24,
+            paddingTop: 10,
+            paddingBottom: 10
+        }
+        return (
+            <Select.Option value={item.name} style={optionStyle} showTick={true}  {...item} key={item.email}>
+               <Avatar size="small" src={item.avatar} />
+                <div style={{ marginLeft: 8 }}>
+                    <div style={{ fontSize: 14 }}>{item.name}</div>
+                    <div style={{ color: 'var(--semi-color-text-2)', fontSize: 12, lineHeight: '16px', fontWeight: 'normal' }}>{item.email}</div>
+                </div>
+            </Select.Option>
+        )
+    }
+
+    render() {
+        const { list } = this.state;
+        return (
+            <React.Fragment>
+                <Select
+                    style={{ width: 280, height: 40 }}
+                    onChange={v=>console.log(v)}
+                    defaultValue={'XiaKeMan'}
+                    renderSelectedItem={this.renderSelectedItem}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+                <Select
+                    maxTagCount={2}
+                    style={{width: 280, marginTop: 20}}
+                    onChange={v=>console.log(v)}
+                    defaultValue={['XiaKeMan', 'ShenYue']}
+                    multiple
+                    renderSelectedItem={this.renderMultipleWithCustomTag}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+                <Select
+                    maxTagCount={2}
+                    style={{width: 280, marginTop: 20}}
+                    onChange={v=>console.log(v)}
+                    defaultValue={['XiaKeMan', 'ShenYue']}
+                    multiple
+                    renderSelectedItem={this.renderMultipleWithCustomTag2}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+            </React.Fragment>
+        );
+    }
+}
+
+```
+
+### Custom pop-up layer style
+
+You can control the style of the pop-up layer through `dropdownClassName`, `dropdownStyle`  
+For example, when you customize the width of the pop-up layer, you can pass the width through `drowndownStyle`
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+    <Select style={{ width: 180 }} dropdownStyle={{ width: 250 }} dropdownClassName="test">
+        <Select.Option value="tiktok">Tiktok</Select.Option>
+        <Select.Option value="hotsoon">Hotsoon</Select.Option>
+        <Select.Option value="pipixia">Pipixia</Select.Option>
+        <Select.Option value="xigua">BuzzVideo</Select.Option>
+    </Select>
+)
+```
+
+### Dynamic Modification Options
+
+If you need to update Options dynamically, you should use controlled value
+
+```jsx live=true
+import React from 'react';
+import { Select, Button } from '@douyinfe/semi-ui';
+
+() => {
+    let [options, setOptions] = useState([1, 2, 3, 4]);
+    function add() {
+        let length = Math.ceil(Math.random() * 10);
+        let newOptions = Array.from({ length }, (v, i) => i + 1);
+        setOptions(newOptions);
+    }
+    return (
+        <>
+            <Select style={{ width: '180px' }} value={4}>
+                {options.map(option => (
+                    <Select.Option value={option} key={option}>
+                        {option}
+                    </Select.Option>
+                ))}
+            </Select>
+            <br />
+            <br />
+            <Button onClick={add}>ChangeOptions Dynamic</Button>
+        </>
+    );
+};
+```
+
+
+### Get all attrbute of selected option
+
+By default, through `onChange` uou can only get value attribute of selected option.  
+If you need to take other attributes of the selected option, you can use `onChangeWithObject` Properties  
+At this time, the argument of `onChange` will be object, containing various attributes of selected option, eg: `onChange({ value, label, ...rest })`  
+Note that when onChange With Object is set to true,`defaultValue`/`Value`it should also be object and must have `value` key
+
+```jsx live=true
+import React from 'react';
+import { Select, TextArea } from '@douyinfe/semi-ui';
+
+() => {
+    const list = [
+        { value: 'tiktok', label: 'Tiktok', type: 1 },
+        { value: 'capcut', label: 'Capcut', type: 2 },
+        { value: 'xigua', label: 'BuzzVideo', type: 3 },
+    ];
+    const [cbValue, setCbValue] = useState();
+    const [multipleCbValue, setMultipleCbValue] = useState();
+
+    const onChange = value => {
+        setCbValue(value);
+        console.log(value);
+    };
+
+    const onMultipleChange = value => {
+        setMultipleCbValue(value);
+        console.log(value);
+    };
+
+    return (
+        <div>
+            <div>
+                <Select
+                    style={{ width: 150 }}
+                    onChangeWithObject
+                    optionList={list}
+                    defaultValue={list[0]}
+                    onChange={onChange}
+                ></Select>
+                <h4>onChang callback:</h4>
+                <TextArea style={{ width: 320, marginBottom: 48 }} autosize value={JSON.stringify(cbValue)} rows={2} />
+            </div>
+            <div>
+                <Select
+                    style={{ width: 320 }}
+                    onChangeWithObject
+                    multiple
+                    optionList={list}
+                    onChange={onMultipleChange}
+                    placeholder="Multiple Select"
+                >
+                </Select>
+                <h4>onChange callback:</h4>
+                <TextArea style={{ width: 320 }} autosize value={JSON.stringify(multipleCbValue)} />
+            </div>
+        </div>
+    );
+};
+```
+
+
+### Create entries
+
+You can create and select entries that do not exist in the options by setting `allowCreate=true` You can customize the content display when creating the label through renderCreateItem (by returning ReactNode, note that you need to customize the style) In addition, can be used with the `defaultActiveFirstOption` property to automatically select the first item. When you enter directly and press Enter, you can immediately create an Option
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    const optionList = [
+        { value: 'tiktok', label: 'Tiktok' },
+        { value: 'capcut', label: 'Capcut' },
+        { value: 'xigua', label: 'BuzzVideo' },
+    ];
+    return (
+        <>
+            <Select
+                style={{ width: 400 }}
+                optionList={optionList}
+                allowCreate={true}
+                multiple={true}
+                filter={true}
+                onChange={v => console.log(v)}
+                defaultActiveFirstOption
+            ></Select>
+            <br />
+            <br />
+            <Select
+                style={{ width: 400 }}
+                optionList={optionList}
+                allowCreate={true}
+                multiple={true}
+                filter={true}
+                renderCreateItem={input => <div style={{ padding: 10 }}>Create Item:{input}</div>}
+                onChange={v => console.log(v)}
+                defaultActiveFirstOption
+            ></Select>
+        </>
+    );
+};
+```
+
+### Virtualize
+Turn on list virtualization when passing in `virtualize` to optimize performance when there are a large number of Option nodes
+virtualize is an object containing the following values:
+
+- height: Option list height value, default 300
+- width: Option list width value, default 100%
+- itemSize: The height of each line of Option, must be passed
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class VirtualizeDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        let newOptions = Array.from({ length: 3000 }, (v, i) => ({ label: `option-${i}`, value: i }));
+        this.state = {
+            optionList: newOptions,
+        };
+    }
+
+    render() {
+        let { groups, optionList } = this.state;
+        let virtualize = {
+            height: 300,
+            width: '100%',
+            itemSize: 36, // px
+        };
+        return (
+            <>
+                <Select
+                    placeholder="3000 options"
+                    style={{ width: 260 }}
+                    filter
+                    onSearch={this.handleSearch}
+                    virtualize={virtualize}
+                    optionList={optionList}
+                ></Select>
+            </>
+        );
+    }
+}
+```
+
+### Custom Trigger
+
+If the default layout style of the selection box does not meet your needs, you can use `triggerRender` to customize the display of the selection box
+
+The parameters of triggerRender are as follows
+
+```typescript
+interface triggerRenderProps {
+  value: array<object> // All currently selected options
+  inputValue: string; // The input value of the current input box
+  onChange: (inputValue: string) => void; // The function used to update the value of the input box. You should call this function when the value of the Input component you customize in triggerRender is updated to synchronize the state to the Select internal
+  onClear: () => void; // Function to clear the value
+  disabled: boolean; // Whether to disable Select
+  placeholder: string; // Select placeholder
+  componentProps: //All props passed to Select by users
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { IconAppCenter, IconChevronDown } from '@douyinfe/semi-icons';
+
+() => {
+    const [valList, setValList] = useState(['tiktok', 'hotsoon']);
+    const [val, setVal] = useState('tiktok');
+    const list = [
+        { value: 'tiktok', label: 'Tiktok' },
+        { value: 'hotsoon', label: 'Hotsoon' },
+        { value: 'pipixia', label: 'Pipixia' },
+        { value: 'toutiao', label: 'TooBuzz' },
+    ];
+    const triggerRender = ({ value }) => {
+        return (
+            <div
+                style={{
+                    minWidth: '112',
+                    backgroundColor: 'var(--semi-color-primary-light-default)',
+                    height: 32,
+                    display: 'flex',
+                    alignItems: 'center',
+                    paddingLeft: 8,
+                    borderRadius: 3,
+                    color: 'var(--semi-color-primary)',
+                }}
+            >
+                <div
+                    style={{
+                        fontWeight: 600,
+                        flexShrink: 0,
+                        fontSize: 14,
+                    }}
+                >
+                    Business Line
+                </div>
+                <div
+                    style={{
+                        margin: 4,
+                        whiteSpace: 'nowrap',
+                        textOverflow: 'ellipsis',
+                        flexGrow: 1,
+                        overflow: 'hidden',
+                    }}
+                >
+                    {value.map(item => item.label).join(' , ')}
+                </div>
+                <IconAppCenter style={{ marginRight: 8, flexShrink: 0 }} />
+            </div>
+        );
+    };
+
+    const triggerRender2 = ({ value }) => {
+        return (
+            <div
+                style={{
+                    minWidth: '112',
+                    height: 32,
+                    display: 'flex',
+                    alignItems: 'center',
+                    paddingLeft: 8,
+                    borderRadius: 3,
+                }}
+            >
+                <IconChevronDown style={{ color: 'var(--semi-color-tertiary)' }} />
+                <div
+                    style={{
+                        margin: 4,
+                        whiteSpace: 'nowrap',
+                        textOverflow: 'ellipsis',
+                        flexGrow: 1,
+                        overflow: 'hidden',
+                        display: 'flex',
+                        alignItems: 'center',
+                        color: 'var(--semi-color-tertiary)',
+                    }}
+                >
+                    {value.map(item => item.label).join(' , ')}
+                </div>
+            </div>
+        );
+    };
+    return (
+        <div>
+            <h4>Different background Trigger</h4>
+            <Select
+                value={valList}
+                triggerRender={triggerRender}
+                optionList={list}
+                onChange={value => setValList(value)}
+                multiple
+                style={{ width: 240 }}
+            ></Select>
+            <br />
+            <br />
+            <h4>Borderless and transparent Trigger</h4>
+            <Select
+                value={val}
+                onChange={value => setVal(value)}
+                triggerRender={triggerRender2}
+                optionList={list}
+                style={{ width: 240, marginTop: 20, outline: 0 }}
+            ></Select>
+        </div>
+    );
+};
+```
+
+### Custom Option Render
+
+- Simple customization: Pass the label property of Option or children into ReactNode, you can control the rendering of the candidates, and the content will automatically bring styles such as padding, background color, etc.  
+- Complete customization: By passing in `renderOptionItem`, you can completely take over the rendering of the candidates in the list, and get the relevant state values from the callback input parameters. Achieve a higher degree of freedom of structural rendering  
+  Notice:
+  1. The style passed in by props needs to be consumed on wrapper dom, otherwise it will not be able to be used normally in virtualization scenarios  
+  2. The styles of selected, focused, disabled, etc. state need to be added by yourself, and you can get the relative boolean value from props
+  3. onMouseEnter needs to be bound on the wrapper dom, otherwise the display will be problematic when the upper and lower keyboards are operated
+  4. If your custom item is Select.Option, you need to pass renderProps.onClick transparently to the onSelect prop of Option
+
+```jsx live=true
+import React from 'react';
+import { Select, Checkbox } from '@douyinfe/semi-ui';
+
+() => {
+    const renderOptionItem = renderProps => {
+        const {
+            disabled,
+            selected,
+            label,
+            value,
+            focused,
+            className,
+            style,
+            onMouseEnter,
+            onClick,
+            empty,
+            emptyContent,
+            ...rest
+        } = renderProps;
+        const optionCls = classNames({
+            ['custom-option-render']: true,
+            ['custom-option-render-focused']: focused,
+            ['custom-option-render-disabled']: disabled,
+            ['custom-option-render-selected']: selected,
+        });
+        // Notice:
+        // 1. The style passed in by props needs to be consumed on wrapper dom, otherwise it will not be able to be used normally in virtualization scenarios
+        // 2. The styles of selected (selected), focused (focused), disabled (disabled) and other states need to be added by yourself, you can get the relative boolean value from props
+        // 3.onMouseEnter needs to be bound on the wrapper dom, otherwise the display will be problematic when the upper and lower keyboards are operated
+
+        return <div style={style} className={optionCls} onClick={() => onClick()} onMouseEnter={(e) => onMouseEnter()}>
+            <Checkbox checked={selected} />
+            <div className='option-right'>
+                {label}
+            </div>
+        </div>
+    };
+
+    const optionList = [
+      { value: 'tiktok', label: 'Tiktok', otherKey:0 },
+      { value: 'capcut', label: 'Capcut', disabled: true, otherKey: 1 },
+      { value: 'cam', label: 'UlikeCam', otherKey: 2 },
+      { value: 'buzz', label: 'Buzz', otherKey: 3 },
+    ];
+
+    return <>
+        <Select
+            filter
+            defaultOpen
+            defaultValue='tiktok'
+            dropdownClassName='components-select-demo-renderOptionItem'
+            optionList={optionList}
+            style={{ width: 180 }}
+            renderOptionItem={renderOptionItem}
+        />
+        <br/>
+        <br/>
+        <Select
+            filter
+            placeholder='multiple'
+            multiple
+            dropdownClassName='components-select-demo-renderOptionItem'
+            optionList={optionList}
+            style={{ width: 320, marginTop: 180 }}
+            renderOptionItem={renderOptionItem}
+        />
+    </>
+};
+```
+
+```scss
+.components-select-demo-renderOptionItem {
+    .custom-option-render {
+        display: flex;
+        font-size: 14px;
+        line-height: 20px;
+        word-break: break-all;
+        padding-left: 12px;
+        padding-right: 12px;
+        padding-top: 8px;
+        padding-bottom: 8px;
+        color: var(--semi-color-text-0);
+        position: relative;
+        display: flex;
+        align-items: center;
+        cursor: pointer;
+        box-sizing: border-box;
+        .option-right {
+            margin-left: 8px;
+            display: inline-flex;
+            align-items: center;
+        }
+        &:active {
+            background-color: var(--semi-color-fill-1);
+        }
+        &-focused {
+            background-color: var(--semi-color-fill-0);
+        }
+        &-selected {
+            //font-weight: 700;
+        }
+        &-disabled {
+            color: var(--semi-color-disabled-text);
+            cursor: not-allowed;
+        }
+        &:first-of-type {
+            margin-top: 4px;
+        }
+        &:last-of-type {
+            margin-bottom: 4px;
+        }
+    }
+}
+```
+
+## API reference
+
+### Select Props
+
+| Properties | Instructions | Type | Default |
+| --- | --- | --- | --- |
+| allowCreate | Whether to allow the user to create new entries. Needs to be used with `filter` | boolean | false |
+| arrowIcon | Customize the right drop-down arrow Icon, when the showClear switch is turned on and there is currently a selected value, hover will give priority to the clear icon <br/>**since v1.15.0** | ReactNode |  |
+| autoAdjustOverflow | Whether the pop-up layer automatically adjusts the direction when it is obscured (only vertical direction is supported for the time being, and the inserted parent is body) | boolean | true |
+| autoFocus | Whether automatically focus when component mount | boolean | false |
+| className | The CSS class name of the wrapper element | string |  |
+| clickToHide | When expanded, click on the selection box to automatically put away the drop-down list | boolean | false |
+| defaultValue | Originally selected value when component mount | string\|number\|array |  |
+| defaultOpen | Whether show dropdown when component mounted | boolean | false |
+| defaultActiveFirstOption | Whether to highlight the first option by default (press Enter to select directly) | boolean | false |
+| disabled | Whether disabled component | boolean | false |
+| dropdownClassName | ClassName of the pop-up layer | string |  |
+| dropdownMatchSelectWidth | Is the minimum width of the drop-down menu equal to Select | boolean | true |
+| dropdownStyle | The inline style of the pop-up layer | object |  |
+| emptyContent | Content displayed when there is no result. When set to null, the drop-down list will not be displayed | string | ReactNode |  |
+| filter | Whether searchable or not, the default is false. When `true` is passed, it means turn on search ability, default filtering policy is whether the label matches search input<br/>When the input type is function, the function arguments are searchInput, option. It should return true when the option meets the filtering conditions, otherwise it returns false. | false | boolean\|function |  |
+| getPopupContainer | Specifies the parent DOM, and the popup layer will be rendered to the DOM, you need to set 'position: relative`| function(): HTMLElement | () => document.body |
+| innerTopSlot | Render at the top of the pop-up layer, custom slot inside the optionList <br/>** supported after v1.6.0 ** | ReactNode |  |
+| innerBottomSlot | Render at the bottom of the pop-up layer, custom slot inside the optionList | ReactNode |  |
+| insetLabel | Same to `prefix`, just an alias | ReactNode |  |
+| loading | Does the drop-down list show the loading animation | boolean | false |
+| max | Maximum number of choices, effective only in multi-selection mode | number |  |
+| maxTagCount | In multi-selection mode, when the option is beyond maxTag Count, the subsequent option is rendered in the form of + N | number |  |
+| maxHeight | Maximum height of `optionList` in the pop-up layer | string | number | 300 |
+| multiple | Whether allow multiple selection | boolean | false |
+| outerBottomSlot | Rendered at the bottom of the pop-up layer, custom slot level with optionList | ReactNode |  |
+| outerTopSlot | Rendered at the top of the pop-up layer, custom slot level with optionList <br/>** supported after v1.6.0 ** |
+| optionList | You can pass Option through this property, make sure that each element in the array has `label`, `value` properties | Array (\[{value, label}\]) |  |
+| placeholder | placeholder | ReactNode |  |
+| position | Pop-up layer position, refer to [Popover·API reference·position](/en-US/show/popover#API%20Reference) | string | 'bottomLeft' |
+| prefix | An input helper rendered before | ReactNode |  |
+| remote | Whether to turn on remote search, when remote is true, the input content will not be locally filtered and matched | boolean | false |
+| renderCreateItem | When allowCreate is true, you can customize the rendering of the creation label | function(inputValue: string) | InputValue => 'Create' + InputValue |
+| renderSelectedItem | Customize the rendering of selected tabs in the selection box | function(option) |  |
+| showArrow | Whether to show arrow icon | boolean | true |
+| showClear | Whether to show the clear button | boolean | false |
+| size | Size, optional value `default` / `small` / `large` | string | 'default' |
+| spacing | Spacing between popup layer and trigger | number | 4 |
+| style | Inline Style | object |  |
+| suffix | An input helper rendered after | ReactNode |  |
+| triggerRender | Custom DOM of trigger <br/>**supported after v0.34.0** | function |  |
+| virtualize | List virtualization, used to optimize performance in the case of a large number of nodes, composed of height, width, and itemSize <br/>** supported after v0.37.0 ** | object |  |
+| validateStatus | Verification result, optional `warning`, `error`, `default` (only affect the style background color) | string | 'default' |
+| value | The currently selected value is passed as a controlled component, used in conjunction with `onchange` | string\|number\|array |  |
+| zIndex | Popup layer z-index | number | 1030 |
+| onBlur | Callback when blur | function(event) |  |
+| onChange | Callback function when selectd option | function (value) |  |
+| onChangeWithObject | Whether to use the other properties of the selected option as a callback. When set to true, the entry type of onchange changes from string to object: {value, label,...rest} | boolean | false |
+| onClear | Callback when click clear icon | function |  |
+| onCreate | Allow Create is true and provides after the callback when creating the standby option | function |  |
+| onDeselect | Callback when selected cancel | function (value, option) |  |
+| onDropdownVisibleChange | A callback when the drop-down menu expands / collapsed | function(visible: boolean) |  |
+| onExceed | Callback invoked when the number of attempts to select exceeds the max limit, effective only at multi-selection | function |  |
+| onFocus | Callback when focus select | function(event) |  |
+| onSearch | The callback function when the content of the input box changes. | function(sugInput: string) |  |
+| onSelect | Callback when selected | function (value, option) |  |
+
+### Option Props
+
+> **The label of different Option must be unique** . Value allows repetition
+
+| Properties | Instructions | Type | Default |
+| --- | --- | --- | --- |
+| className | The CSS class name of the wrapper element | string |  |
+| disabled | Disbaled | boolean | false |
+| label | Text displayed. Prioritize the label when rendering, take the child, value if not, and downgrade in turn | string\|reactNode |  |
+| showTick | Whether to show the Icon of tick when option selected | boolean | true |
+| style | Inline Style | object |  |
+| value | Property value | string\|number |  |
+
+### OptGroup Props
+
+| Properties | Instructions       | Type      | Version |
+| ---------- | ------------------ | --------- | ------- |
+| className  | The CSS class name | string    | v0.31.0 |
+| label      | Text displayed.    | ReactNode | v0.31.0 |
+| style      | Inline Style       | object    | v0.31.0 |
+
+### Method()
+
+| Method      | Instructions                    | Version |
+| ----------- | ------------------------------- | ------- |
+| close       | Manually close dropdown list    | v0.34.0 |
+| clearInput  | Manually clear value of input   | v1.18.0 |
+| deselectAll | Manually clear selected options | v1.18.0 |
+| focus       | Manually focus select           | v1.11.0 |
+| open        | Manually open dropdown list     | v0.34.0 |
+| selectAll   | Manually select all options     | v1.18.0 |
+
+## Design Tokens
+
+<DesignToken/>
+
+## FAQ
+
+-   **Searchable Select, using remote data to dynamically update the `optionList`, why sometimes there is no data before the asynchronous request is completed??**  
+     Please check whether `remote={true}` is set. If remote is not set, the input value of the input box will be compared with the current optionList by default. If there is no match, no data will be displayed.  
+     You can turn off matching filtering on the current local data by setting remote to true.
+
+-   **Use jsx to declare Option, label is the content after i18n, fail to re-render after switching locale** When the children jsx method declares Options, because it is reactNode, it is impossible to use deepEqual to compare whether the content is updated (excessive performance consumption), so the key of children reactNode will be collected. When the key is unchanged, it is considered that Options have not occurred. Changes will not go through the process of re-collecting data. You can also use locale as part of the Option key.  
+    The problem can also be solved by using `optionList` to pass in. Because the key is relatively limited for the object form, isEqual is used inside Select to determine whether there is a change
+
+-   **Use jsx to declare Option, and fail to re-render after dynamically switching the disabled attribute**   
+    The reason is the same as above, you can set a different key value for Option again, or use optionList to declare candidate options
+
+-   **Will Select automatically limit the width of the drop-down menu?**   
+MinWidth will be given, but width will not be written dead. If necessary, you can add it yourself through dropdownStyle.
+
+-   **After setting allowCreate, dynamically updating optionList or children does not take effect**
+
+    allowCreate is mainly used for locally created scenarios. When this item is turned on, it is equivalent to forcibly taking over optionList/children, and will no longer respond to external updates to these two types of values. Otherwise, how the currently created options are combined with the latest props.optionList, and whether the strategy is overwritten or merged depends largely on the business scenario logic, and it is inappropriate to force presets by the component layer.
+
+-   **Why Semi's Select requires that the label must be unique, but not the value?**
+    First of all, we must need a unique identifier to make a selection judgment. For almost all UI libraries, when using Select.Option, the minimum requirements will only require the two values of label and value to be passed in, instead of requiring a separate key (too cumbersome). Semi continues this setting.    
+    So why is label instead of value in semi's select?  
+    The label of the option is what the user perceives. From an interactive point of view, if there are two options that are exactly the same on the display, to the user’s perception, they look the same and cannot be distinguished, but the selected effects are different (for example, one value is 0, the other As 1), it is unreasonable. (Users' first reaction is often repeated, and there may be a bug)
+Unique label and repeated value are more common in daily use. For example, a selector that selects the company id based on the app name, value is the company id corresponding to the app, and label is the name of the app.

+ 1452 - 0
content/input/select/index.md

@@ -0,0 +1,1452 @@
+---
+localeCode: zh-CN
+order: 25
+category: 输入类
+title:  Select 选择器
+icon: doc-select
+width: 60%
+brief: 用户可以通过 Select 选择器从一个选项集合中去选中一个或多个选项,并呈现最终选择结果
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Select } from '@douyinfe/semi-ui';
+const Option = Select.Option;
+```
+
+<Notice title='注意'>
+Select的直接子元素必须为 Option 或者 OptGroup,不允许为其他Element
+</Notice>
+
+### 基本使用
+
+每个 Option 标签都必须声明 value 属性,Option 的 children 或 label 将会被渲染至下拉列表中  
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Select defaultValue='tiktok' style={{ width: 120 }}>
+        <Select.Option value='tiktok'>抖音</Select.Option>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+        <Select.Option value='jianying' disabled>剪映</Select.Option>
+        <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select style={{ width: '180px' }} defaultValue='tiktok' disabled style={{ width: 120 }}>
+        <Select.Option value='tiktok'>抖音</Select.Option>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select placeholder='请选择业务线' style={{ width: 120 }}>
+        <Select.Option value='tiktok'>抖音</Select.Option>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+        <Select.Option value='jianying' disabled>剪映</Select.Option>
+        <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 以数组形式传入 Option
+
+可以直接通过`optionList`传入一个对象数组,每个对象必须包含 value/label 属性(当然其他属性也可以通过此方式传入)
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  const list = [
+    { value: 'tiktok', label: '抖音', otherKey:0 },
+    { value: 'hotsoon', label: '火山小视频', disabled: true, otherKey: 1 },
+    { value: 'jianying', label: '剪映', otherKey: 2 },
+    { value: 'toutiao', label: '今日头条', otherKey: 3 },
+  ];
+  return (
+    <Select placeholder='请选择业务线' style={{ width: 180 }} optionList={list}>
+    </Select>
+  )
+}
+```
+
+### 多选
+
+配置`multiple`属性,可以支持多选
+
+配置 `maxTagCount` 可以限制已选项展示的数量,超出部分将以+N 的方式展示
+
+配置 `max` 属性可限制最大可选的数量,超出最大限制数量后无法选中,同时会触发`onExceed`回调
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Select multiple style={{ width: '320px' }} defaultValue={['tiktok','hotsoon']}>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select multiple style={{ width: '320px' }} defaultValue={['tiktok','hotsoon', 'jianying']} maxTagCount={2}>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+
+    <br/><br/>
+    <Select multiple style={{ width: '320px' }} defaultValue={['tiktok']} max={2} onExceed={()=>Toast.warning('最多只允许选择两项')}>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 分组
+
+分组功能 v0.31.0 后提供  
+用 OptGroup 进行分组(分组功能仅支持通过jsx方式声明children使用,不支持optionList方式传入)  
+
+<Notice title='注意'>
+  1. OptGroup必须为Select的直接子元素,不允许有Fragment或DIV等其他元素阻隔 <br/>
+  2. 若Select的children需要动态更新,OptGroup上的key也需要进行更新,否则Select无法识别  
+</Notice>
+
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <Select placeholder="" style={{ width: 180 }} filter>
+      <Select.OptGroup label="Asia">
+          <Select.Option value="a-1">China</Select.Option>
+          <Select.Option value="a-2">Koera</Select.Option>
+      </Select.OptGroup>
+      <Select.OptGroup label="Europe">
+          <Select.Option value="b-1">Germany</Select.Option>
+          <Select.Option value="b-2">France</Select.Option>
+      </Select.OptGroup>
+      <Select.OptGroup label="South America">
+          <Select.Option value="c-1">Peru</Select.Option>
+      </Select.OptGroup>
+  </Select>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  const data = [
+    {
+      label: 'Asia',
+      children: [
+        { value: 'a-1', label: 'China' },
+        { value: 'a-2', label: 'Koera' },
+      ]
+    },
+    {
+      label: 'Europe',
+      children: [
+        { value: 'b-1', label: 'Germany' },
+        { value: 'b-2', label: 'France' },
+      ]
+    },
+    {
+      label: 'South America',
+      children: [
+        { value: 'c-1', label: 'Peru' },
+      ]
+    }
+  ];
+  return (
+    <Select placeholder="" style={{ width: 180 }} filter>
+      {
+        data.map(group => (
+          <Select.OptGroup label={group.label} key={group.label}>
+            {
+              group.children.map(option => (
+                <Select.Option value={option.value} key={option.value}>
+                  {option.label}
+                </Select.Option>
+              ))
+            }
+          </Select.OptGroup>
+        ))
+      }
+    </Select>
+  )
+}
+
+```
+
+### 不同尺寸
+
+通过Size控制选择器的大小尺寸: `small` / `default` / `large`
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Select placeholder='请选择业务线' style={{ width: '180px' }} size='small'>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select placeholder='请选择业务线' style={{ width: '180px' }}>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select placeholder='请选择业务线' style={{ width: '180px' }} size='large'>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 不同校验状态样式
+
+validateStatus: default / warning / error  
+仅影响背景颜色等样式表现
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Select style={{ width: '180px' }}>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select style={{ width: '180px' }} validateStatus='warning'>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select style={{ width: '180px' }} validateStatus='error'>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 配置前缀、后缀、清除按钮
+
+-   可以通过`prefix`传入选择框前缀,通过`suffix`传入选择框后缀,可以为文本或者 ReactNode  
+    当 prefix、suffix 传入的内容为文本或者 Icon 时,会自动带上左右间隔,若为自定义 ReactNode,则左右间隔为 0
+-   通过`showClear`控制清除按钮是否展示
+-   通过`showArrow`控制右侧下拉箭头是否展示
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
+
+() => (
+  <>
+    <Select
+      style={{ width: '320px' }}
+      defaultValue={'hotsoon'}
+      prefix={<IconVigoLogo />}
+      showClear={true}
+    >
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select
+      style={{ width: '320px' }}
+      defaultValue={'hotsoon'}
+      prefix={<IconVigoLogo />}
+      suffix={<IconGift />}
+      showArrow={false}
+    >
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 内嵌标签
+
+通过设置`insetLabel`,你可以给 Select 设置 label,可以传入 string 或者 ReactNode  
+当传入类型为 ReactNode 时,注意要自行处理 label 与文本之间的间隔
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  const list = [
+    { value: 'tiktok', label: '抖音' },
+    { value: 'hotsoon', label: '火山小视频' },
+    { value: 'jianying', label: '剪映' },
+    { value: 'toutiao', label: '今日头条' },
+  ]
+  return (
+    <>
+      <Select style={{ width: 300 }} optionList={list} insetLabel='业务线' defaultValue='tiktok'>
+      </Select>
+      <br/><br/>
+      <Select
+        style={{ width: 300 }}
+        optionList={list} placeholder='请选择业务线'
+        insetLabel={<span style={{marginRight: 0, marginLeft: 10, color: "var(--semi-color-text-2)"}}>业务线</span>}>
+      </Select>
+    </>
+  )
+}
+```
+
+### 在顶部/底部渲染附加项
+
+我们在弹出层顶部、底部分别预留了插槽,当你需要在弹出层中添加自定义 node 时  
+可以通过`innerBottomSlot`或者`outerBottomSlot`传入,自定义 node 将会被渲染在弹出层底部;可以通过`innerTopSlot`或者`outerTopSlot`传入,自定义 node 将会被渲染在弹出层顶部。
+
+-   `innerTopSlot` 和 `innerBottomSlot`将会被渲染在 optionList 内部,当滚动到 optionList 顶部/底部时展现
+-   `outerTopSlot` 和 `outerBottomSlot`将会被渲染为与 optionList 平级,无论 optionList 是否滚动,都会始终展现
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+    let selectStyle = { width: 180, margin: 20 };
+    let innerSlotStyle = {
+          backgroundColor: '#FFF',
+          height: '36px',
+          display: 'flex',
+          alignItems: 'center',
+          cursor: 'pointer',
+          marginLeft: 32,
+          borderRadius: '0 0 6px 6px',
+          color: '#0077FA'
+    };
+    let innerSlotNode = (<div style={innerSlotStyle}>
+        点击加载更多
+    </div>);
+    let outSlotStyle = {
+          backgroundColor: 'whitesmoke',
+          height: '36px',
+          display: 'flex',
+          paddingLeft: 32,
+          color: '#0077FA',
+          alignItems: 'center',
+          cursor: 'pointer',
+          borderRadius: '0 0 6px 6px',
+    };
+    let outSlotNode = (<div style={outSlotStyle}>
+        <span style={{color: '#0077FA'}}>未找到应用?</span>
+    </div>);
+
+    return (
+      <div>
+          <p>outerBottomSlot:</p>
+          <Select
+              style={selectStyle}
+              dropdownStyle={{ width: 180 }}
+              maxHeight={150}
+              outerBottomSlot={outSlotNode}
+              placeholder='自定义外侧底部slot'
+              defaultOpen
+              autoAdjustOverflow={false}
+              position='bottom'
+          >
+                <Select.Option value='tiktok'>抖音</Select.Option>
+                <Select.Option value='hotsoon'>火山</Select.Option>
+                <Select.Option value='jianying'>剪映</Select.Option>
+                <Select.Option value='duoshan'>多闪</Select.Option>
+                <Select.Option value='xigua'>西瓜视频</Select.Option>
+          </Select>
+          <p style={{ marginTop: 200 }}>innerBottomSlot:</p>
+          <Select
+              style={selectStyle}
+              dropdownStyle={{ width: 180 }}
+              maxHeight={150}
+              innerBottomSlot={innerSlotNode}
+              placeholder='自定义内侧底部slot'
+          >
+                <Select.Option value='tiktok'>抖音</Select.Option>
+                <Select.Option value='hotsoon'>火山</Select.Option>
+                <Select.Option value='jianying'>剪映</Select.Option>
+                <Select.Option value='duoshan'>多闪</Select.Option>
+                <Select.Option value='xigua'>西瓜视频</Select.Option>
+          </Select>
+        </div>
+    )
+}
+```
+
+通过 outerTopSlot 将内容插入顶部插槽
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+          key: 'component',
+        };
+        this.list = {
+          component: [
+              { value: 'select', label: '选择器' },
+              { value: 'tabs', label: '标签' },
+              { value: 'avatar', label: '头像' },
+              { value: 'button', label: '按钮' },
+          ],
+          design: [
+              { value: 'color', label: '颜色' },
+              { value: 'dark', label: '暗色模式' },
+              { value: 'icon', label: '图标' },
+              { value: 'font', label: '字体' },
+          ],
+          feedback: [
+              { value: 'faq', label: '常见问题' },
+              { value: 'join', label: '加入用户群' },
+              { value: 'hornbill', label: '犀鸟反馈问题' },
+          ],
+        }
+        this.handleTabClick = this.handleTabClick.bind(this);
+    };
+
+    handleTabClick(itemKey) {
+      this.setState({key: itemKey});
+    };
+
+    render() {
+        const { key } = this.state;
+        const tabStyle = {
+          cursor: 'pointer',
+          marginRight: 12,
+          paddingBottom: 4,
+        };
+        const tabActiveStyle = {
+          ...tabStyle,
+          borderBottom: '1px solid var(--semi-color-primary)',
+          fontWeight: 700,
+        }
+        const tabWrapper = {
+          display: 'flex',
+          paddingTop: 8,
+          paddingLeft: 32,
+          borderBottom: '0.5px solid var(--semi-color-border)'
+        };
+        const tabOptions = [
+          {itemKey: 'component', label: '组件'},
+          {itemKey: 'design', label: '设计'},
+          {itemKey: 'feedback', label: '反馈'},
+        ];
+        const outerTopSlotNode = (
+            <div style={tabWrapper}>
+              {
+                tabOptions.map((item, index) => {
+                    style = item.itemKey === key ? tabActiveStyle : tabStyle;
+                    return (
+                      <div style={style} key={item.itemKey} onClick={() => this.handleTabClick(item.itemKey)}>{item.label}</div>
+                    );
+                })
+              }
+            </div>
+        );
+
+        return (
+            <div>
+               <Select
+                  defaultOpen
+                  autoAdjustOverflow={false}
+                  position='bottom'
+                  style={{width: 200}}
+                  outerTopSlot={outerTopSlotNode}
+                  optionList={this.list[key]}
+                />
+            </div>
+        );
+    };
+}
+```
+
+### 受控组件
+
+传入 value 时 Select 为受控组件,所选中的值完全由 value 决定。
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  let [value, setValue] = useState('xigua');
+  return (
+    <>
+      <Select value={value} style={{ width: '300px' }} onChange={setValue} placeholder='受控的Select'>
+        <Select.Option value='tiktok'>抖音</Select.Option>
+        <Select.Option value='hotsoon'>火山</Select.Option>
+        <Select.Option value='jianying'>剪映</Select.Option>
+        <Select.Option value='xigua'>西瓜视频</Select.Option>
+      </Select>
+    </>
+  )
+}
+```
+
+### 动态修改 Options
+
+如果需要动态更新 Options,应该使用受控的 value
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { Select, Button } from '@douyinfe/semi-ui';
+
+() => {
+  let [options, setOptions] = useState([1, 2, 3, 4]);
+  function add() {
+    let length = Math.ceil(Math.random() * 10);
+    let newOptions = Array.from({length}, (v,i) => i+1);
+    setOptions(newOptions);
+  }
+  return (
+    <>
+      <Select style={{ width: '180px' }} placeholder='请选择' value={4}>
+        {options.map(option => (
+          <Select.Option
+            value={option}
+            key={option}>
+            {option}
+          </Select.Option>
+        ))}
+      </Select>
+      <br/><br/>
+      <Button onClick={add}>
+        changeOptions Dynamic
+      </Button>
+    </>
+  );
+}
+```
+
+### 联动
+
+使用受控value,实现不同Select之间的联动。如果是带有层级关系的复杂联动建议直接使用`Cascader`组件
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class Link extends React.Component {
+    get provinces() {
+        return ['四川', '广东'];
+    }
+    get maps() {
+        return {
+            '四川': ['成都', '都江堰'],
+            '广东': ['广州', '深圳', '东莞'],
+        };
+    }
+    constructor() {
+        super();
+        this.state = {
+            provinces: this.provinces,
+            maps: this.maps,
+            citys: this.maps[this.provinces[0]],
+            city: this.maps[this.provinces[0]][0]
+        };
+        this.provinceChange = this.provinceChange.bind(this);
+        this.cityChange = this.cityChange.bind(this);
+    }
+
+    provinceChange(newProvince) {
+        const { maps } = this.state;
+        this.setState({ citys: maps[newProvince], city: maps[newProvince][0] });
+    }
+    cityChange(city) {
+        this.setState({ city });
+    }
+    render() {
+        const { provinces, citys, city } = this.state;
+        return (
+            <React.Fragment>
+                <Select
+                    style={{ width: '150px', margin: '10px' }}
+                    onChange={this.provinceChange}
+                    defaultValue={provinces[0]}
+                >
+                    {provinces.map(pro => (
+                        <Select.Option value={pro} key={pro}>{pro}</Select.Option>
+                    ))}
+                </Select>
+                <Select
+                    style={{ width: '150px', margin: '10px'  }}
+                    value={city} onChange={this.cityChange}>
+                    {citys.map(c => (
+                        <Select.Option value={c} key={c}>{c}</Select.Option>
+                    ))}
+                </Select>
+            </React.Fragment>
+        );
+    }
+}
+```
+
+### 开启搜索
+
+将 `filter` 置为 true,开启搜索能力。默认搜索策略将为 input 输入值与 option 的 label 值进行 include 对比
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <>
+    <Select filter style={{ width: 180 }} placeholder='带搜索功能的单选'>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+    <br/><br/>
+    <Select filter multiple style={{ width: 300 }} placeholder='带搜索功能的多选'>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+    </Select>
+  </>
+)
+```
+
+### 远程搜索
+
+带有远程搜索,防抖请求,加载状态的多选示例  
+通过`filter`开启搜索能力  
+将`remote`设置为 true 关闭对当前数据的筛选过滤(在 v0.24.0 后提供)  
+通过动态更新`optionList`更新下拉菜单中的备选项  
+使用受控的 value 属性
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { debounce } from 'lodash-es';
+import { Select } from '@douyinfe/semi-ui';
+
+class SearchDemo extends React.Component {
+    constructor(){
+        super();
+        this.state = {
+            loading: false,
+            optionList: [
+                { value: 'tiktok', label: '抖音', type: 1 },
+                { value: 'hotsoon', label: '火山小视频', type: 2 },
+                { value: 'jianying', label: '剪映', type: 3 },
+                { value: 'toutiao', label: '今日头条', type: 4 },
+            ],
+            value: '',
+            multipleValue: [],
+        };
+        this.handleSearch = debounce(this.handleSearch, 800).bind(this);
+        this.onChange = this.onChange.bind(this);
+        this.onMultipleChange = this.onMultipleChange.bind(this);
+    }
+
+    handleSearch(inputValue) {
+        this.setState({ loading: true });
+        let length = Math.ceil(Math.random()*100);
+        let result = Array.from({ length }, (v, i) => {
+            return { value: inputValue + i, label: inputValue + '-新业务线-' + i, type: i + 1 }
+        });
+        setTimeout(() => {
+            this.setState({ optionList: result, loading: false });
+        }, 2000);
+    }
+
+    onChange(value) {
+        this.setState({ value });
+    }
+
+    onMultipleChange(multipleValue) {
+        this.setState({ multipleValue });
+    }
+
+    render() {
+        const { loading, optionList, value, multipleValue } = this.state;
+        return (
+            <div>
+                <Select
+                    style={{ width: 300 }}
+                    filter
+                    remote
+                    onChangeWithObject
+                    onSearch={this.handleSearch}
+                    optionList={optionList}
+                    loading={loading}
+                    onChange={this.onChange}
+                    value={value}
+                    placeholder='请选择'
+                    emptyContent={null}
+                >
+                </Select>
+                <br/><br/>
+                <Select
+                    style={{ width: 300 }}
+                    filter
+                    remote
+                    onChangeWithObject
+                    multiple
+                    value={multipleValue}
+                    onSearch={this.handleSearch}
+                    optionList={optionList}
+                    loading={loading}
+                    onChange={this.onMultipleChange}
+                    placeholder='请选择'
+                    emptyContent={null}
+                >
+                </Select>
+            </div>
+        );
+    }
+
+}
+```
+
+### 自定义搜索逻辑
+
+可以将 `filter` 置为自定义函数,定制你想要的搜索策略  
+如下例子,选项 label 值都是大写,默认的检索策略是字符串 include 对比,会区分大小写。  
+通过传入自定义 `filter` 函数,检索时输入小写字母也能搜到相应内容。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  function searchLabel(sugInput, option) {
+    let label = option.label.toUpperCase();
+    let sug = sugInput.toUpperCase();
+    return label.includes(sug);
+  }
+  return (
+    <Select filter={searchLabel} style={{ width: '180px' }} placeholder='try tiktok'>
+        <Select.Option value='tiktok'>TIKTOK</Select.Option>
+        <Select.Option value='hotsoon'>HOTSOON</Select.Option>
+        <Select.Option value='jianying'>PIPIXIA</Select.Option>
+        <Select.Option value='xigua'>XIGUA</Select.Option>
+    </Select>
+  )
+}
+```
+
+### 自定义已选项标签渲染
+
+默认情况下,选中选项后会将 option.label 或 option.children 的内容回填到选择框中  
+但你可以通过 `renderSelectedItem` 自定义选择框中已选项标签的渲染结构
+
+-   单选时 `renderSelectedItem(optionNode:object) => content:ReactNode`
+-   多选时 `renderSelectedItem(optionNode:object, { index:number, onClose:function }) => { isRenderInTag:bool, content:ReactNode }`
+    -   isRenderInTag 为 true 时,会自动将 content 包裹在 Tag 中渲染(带有背景色以及关闭按钮)
+    -   isRenderInTag 为 false 时,将直接渲染返回的 content
+
+```jsx live=true
+import React from 'react';
+import { Select, Avatar, Tag } from '@douyinfe/semi-ui';
+
+class CustomRender extends React.Component {
+
+    constructor() {
+        super();
+        this.state = {
+          list: [
+            { "name": "夏可漫", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"},
+            { "name": "申悦", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg"},
+            { "name": "曲晨一", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg"},
+            { "name": "文嘉茂", "email": "[email protected]", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png"},
+          ]
+        };
+    }
+
+    renderSelectedItem(optionNode) {
+        return (
+          <div key={optionNode.email} style={{display: 'flex', alignItems: 'center'}}>
+            <Avatar src={optionNode.avatar} size="small">{optionNode.abbr}</Avatar>
+            <span style={{ marginLeft: 8 }}>{optionNode.email}</span>
+          </div>
+        )
+    }
+
+    // avatarSrc & avatarShape are supported after 1.6.0
+    renderMultipleWithCustomTag(optionNode, { onClose }) {
+        let content = (
+            <Tag
+                avatarSrc={optionNode.avatar}
+                avatarShape='circle'
+                closable={true}
+                onClose={onClose}
+                size='large'
+                key={optionNode.name}
+                >
+                {optionNode.name}
+            </Tag>
+        );
+        return {
+          isRenderInTag: false,
+          content
+        };
+    }
+
+    renderMultipleWithCustomTag2(optionNode, { onClose }) {
+        let content = (
+            <Tag
+                avatarSrc={optionNode.avatar}
+                avatarShape='square'
+                closable={true}
+                onClose={onClose}
+                size='large'
+                key={optionNode.name}
+                >
+                {optionNode.name}
+            </Tag>
+        );
+        return {
+          isRenderInTag: false,
+          content
+        };
+    }
+
+    renderCustomOption(item) {
+        let optionStyle = {
+            display: 'flex',
+            paddingLeft: 24,
+            paddingTop: 10,
+            paddingBottom: 10
+        }
+        return (
+            <Select.Option value={item.name} style={optionStyle} showTick={true}  {...item} key={item.email}>
+               <Avatar size="small" src={item.avatar} />
+                <div style={{ marginLeft: 8 }}>
+                    <div style={{ fontSize: 14 }}>{item.name}</div>
+                    <div style={{ color: 'var(--semi-color-text-2)', fontSize: 12, lineHeight: '16px', fontWeight: 'normal' }}>{item.email}</div>
+                </div>
+            </Select.Option>
+        )
+    }
+
+    render() {
+        const { list } = this.state;
+        return (
+            <React.Fragment>
+                <Select
+                    placeholder='请选择'
+                    style={{ width: 280, height: 40 }}
+                    onChange={v=>console.log(v)}
+                    defaultValue={'夏可漫'}
+                    renderSelectedItem={this.renderSelectedItem}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+                <Select
+                    placeholder='请选择'
+                    maxTagCount={2}
+                    style={{width: 280, marginTop: 20}}
+                    onChange={v=>console.log(v)}
+                    defaultValue={['夏可漫', '申悦']}
+                    multiple
+                    renderSelectedItem={this.renderMultipleWithCustomTag}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+                <Select
+                    placeholder='请选择'
+                    maxTagCount={2}
+                    style={{width: 280, marginTop: 20}}
+                    onChange={v=>console.log(v)}
+                    defaultValue={['夏可漫', '申悦']}
+                    multiple
+                    renderSelectedItem={this.renderMultipleWithCustomTag2}
+                >
+                    {
+                      list.map(item => this.renderCustomOption(item))
+                    }
+                </Select>
+            </React.Fragment>
+        );
+    }
+}
+```
+
+### 自定义弹出层样式
+
+你可以通过 dropdownClassName、dropdownStyle 控制弹出层的样式  
+例如当自定义弹出层的宽度时,可以通过 drowndownStyle 传入 width
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => (
+  <Select placeholder='自定义弹出层样式的' style={{ width: 180 }} dropdownStyle={{ width: 250 }} dropdownClassName='test'>
+      <Select.Option value='tiktok'>抖音</Select.Option>
+      <Select.Option value='hotsoon'>火山</Select.Option>
+      <Select.Option value='jianying'>剪映</Select.Option>
+      <Select.Option value='xigua'>西瓜视频</Select.Option>
+  </Select>
+)
+```
+
+### 获取选项的其他属性
+
+默认情况下`onChange`只能拿到 value,如果需要拿选中节点的其他属性,可以使用`onChangeWithObject`属性  
+此时`onChange`函数的入参将会是 object,包含 option 的各种属性,例如 `onChange({ value, label, ...rest })`  
+
+<Notice title='注意'>
+  当 onChangeWithObject 置为 true 时,`defaultValue`/`Value`也应为 object,且须带有`value`、`label` key
+</Notice>
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select, TextArea } from '@douyinfe/semi-ui';
+
+() => {
+    const list = [
+      { value: 'tiktok', label: '抖音', type: 1 },
+      { value: 'hotsoon', label: '火山', type: 2 },
+      { value: 'jianying', label: '剪映', type: 3 },
+      { value: 'toutiao', label: '今日头条', type: 4 },
+    ];
+    const [cbValue, setCbValue] = useState();
+    const [multipleCbValue, setMultipleCbValue] = useState();
+
+    const onChange = (value) => {
+      setCbValue(value);
+      console.log(value);
+    };
+
+    const onMultipleChange = (value) => {
+      setMultipleCbValue(value);
+      console.log(value);
+    };
+
+    return (
+        <div>
+          <div>
+            <Select
+                style={{ width: 150 }}
+                onChangeWithObject
+                optionList={list}
+                placeholder='单选'
+                defaultValue={list[0]}
+                onChange={onChange}
+            >
+            </Select>
+            <h4>onChange回调:</h4>
+            <TextArea style={{ width: 320, marginBottom: 48 }}autosize value={JSON.stringify(cbValue)} rows={2}/>
+          </div>
+          <div>
+              <Select
+                  style={{ width: 320 }}
+                  onChangeWithObject
+                  multiple
+                  optionList={list}
+                  onChange={onMultipleChange}
+                  placeholder='多选'>
+              >
+              </Select>
+              <h4>onChange回调:</h4>
+              <TextArea style={{ width: 320 }} autosize value={JSON.stringify(multipleCbValue)} />
+            </div>
+
+        </div>
+    )
+}
+```
+
+### 创建条目
+
+设置`allowCreate`,可以创建并选中选项中不存在的条目  
+允许通过 `renderCreateItem` 自定义创建标签时的内容显示(通过返回 ReactNode,注意你需要自定义样式),该函数默认值为 (input) => '创建' + input  
+可以配合`defaultActiveFirstOption`属性使用,自动选中第一项,当输入完内容直接回车时,可立即创建  
+
+<Notice title='注意'>
+  当开启allowCreate后,不会再响应对Children或者optionList的更新
+</Notice>
+
+```jsx live=true
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+() => {
+  const optionList = [
+    { value: 'tiktok', label: '抖音' },
+    { value: 'hotsoon', label: '火山小视频' },
+    { value: 'jianying', label: '剪映' },
+    { value: 'toutiao', label: '今日头条' },
+  ]
+  return (
+    <>
+      <Select
+          style={{ width: 400 }}
+          optionList={optionList}
+          allowCreate={true}
+          multiple={true}
+          filter={true}
+          onChange={v => console.log(v)}
+          defaultActiveFirstOption
+      >
+      </Select>
+      <br/><br/>
+      <Select
+        style={{ width: 400 }}
+        optionList={optionList}
+        allowCreate={true}
+        multiple={true}
+        filter={true}
+        placeholder='With renderCreateItem'
+        renderCreateItem={input => <div style={{padding:10}}>Create Item:{input}</div>}
+        onChange={v => console.log(v)}
+        defaultActiveFirstOption
+      >
+      </Select>
+    </>
+  )
+}
+```
+
+### 虚拟化
+
+传入`virtualize`时开启列表虚拟化,用于大量 Option 节点的情况优化性能  
+virtualize 是一个包含下列值的对象:
+
+-   height: Option 列表高度值,默认 300
+-   width: Option 列表宽度值,默认 100%
+-   itemSize: 每行 Option 的高度,必传
+ 
+```jsx live=true hideInDSM
+import React from 'react';
+import { Select } from '@douyinfe/semi-ui';
+
+class VirtualizeDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        let newOptions = Array.from({ length: 3000 }, (v, i) => ({ label: `option-${i}`, value: i }));
+        this.state = {
+            optionList: newOptions,
+        };
+    }
+
+    render() {
+        let { groups, optionList } = this.state;
+        let virtualize = {
+            height: 300,
+            width: '100%',
+            itemSize: 36, // px
+        };
+        return (
+            <>
+                <Select
+                    placeholder="拥有3k个Option的Select"
+                    style={{ width: 260 }}
+                    filter
+                    onSearch={this.handleSearch}
+                    virtualize={virtualize}
+                    optionList={optionList}
+                ></Select>
+            </>
+        );
+    }
+}
+```
+
+### 自定义触发器
+
+如果 Select 默认的触发器样式满足不了你的需求,可以用`triggerRender`自定义选择框的展示
+
+triggerRender 入参如下
+
+```typescript
+interface triggerRenderProps {
+  value: array<object> // 当前所有已选中的options
+  inputValue: string; // 当前input框的输入值
+  onChange: (inputValue: string) => void; // 用于更新 input框值的函数,当你在triggerRender自定义的Input组件值更新时你应该调用该函数,用于向Select内部同步状态
+  onClear: () => void; // 用于清空值的函数
+  disabled: boolean; // 是否禁用Select
+  placeholder: string; // Select的placeholder
+  componentProps: // 所有用户传给Select的props
+}
+```
+
+```jsx live=true
+import React, { useState } from 'react';
+import { Select } from '@douyinfe/semi-ui';
+import { IconAppCenter, IconChevronDown } from '@douyinfe/semi-icons';
+
+() => {
+  const [valList, setValList] = useState(['tiktok', 'hotsoon']);
+  const [val, setVal] = useState('tiktok');
+  const list = [
+    { value: 'tiktok', label: '抖音' },
+    { value: 'hotsoon', label: '火山小视频' },
+    { value: 'jianying', label: '剪映' },
+    { value: 'toutiao', label: '今日头条' },
+  ];
+  const triggerRender = ({ value, }) => {
+    return (
+      <div style={{
+        minWidth: '112',
+        backgroundColor: 'var(--semi-color-primary-light-default)',
+        height: 32,
+        display: 'flex',
+        alignItems: 'center',
+        paddingLeft: 12,
+        borderRadius: 3,
+        color: 'var(--semi-color-primary)'
+      }}
+      >
+        <div style={{
+          fontWeight: 600,
+          flexShrink: 0,
+          fontSize: 14,
+        }}>
+          业务线
+        </div>
+        <div style={{ margin: 4, whiteSpace: 'nowrap', textOverflow: 'ellipsis', flexGrow: 1, overflow: 'hidden' }}>
+           {value.map(item => item.label).join(' , ')}
+        </div>
+        <IconAppCenter style={{ marginRight: 8, flexShrink: 0 }} />
+      </div>
+    );
+  };
+
+  const triggerRender2 = ({ value, ...rest }) => {
+    return (
+      <div style={{
+        minWidth: '112',
+        height: 32,
+        display: 'flex',
+        alignItems: 'center',
+        paddingLeft: 8,
+        borderRadius: 3,
+      }}
+      >
+        <div style={{ margin: 4, whiteSpace: 'nowrap', textOverflow: 'ellipsis', flexGrow: 1, overflow: 'hidden', display: 'flex', alignItems: 'center' }}>
+           {value.map(item => item.label).join(' , ')}
+           <IconChevronDown style={{ margin: '0 8px', flexShrink: 0 }} />
+        </div>
+      </div>
+    );
+  };
+
+  return (
+    <div>
+      <h4>不同背景色的触发器</h4>
+      <Select
+        value={valList}
+        triggerRender={triggerRender}
+        optionList={list}
+        onChange={(value) => setValList(value)}
+        multiple
+        style={{width: 240}}
+      >
+      </Select>
+      <br/><br/>
+      <h4>无边框无背景色的触发器</h4>
+      <Select
+        value={val}
+        onChange={(value) => setVal(value)}
+        triggerRender={triggerRender2}
+        optionList={list}
+        style={{width: 240, marginTop: 20, outline: 0}}
+        >
+      </Select>
+    </div>
+  )
+}
+```
+
+### 自定义候选项渲染
+
+- 简单的自定义:通过Option的label属性或者children传入ReactNode,你可以控制候选项的渲染,此时内容会自动带上内边距、背景色等样式
+- 完全自定义:通过传入`renderOptionItem`,你可以完全接管列表中候选项的渲染,并且从回调入参中,获取到相关的状态值。实现更高自由度的结构渲染  
+  注意事项:
+  1. props传入的style需在wrapper dom上进行消费,否则在虚拟化场景下会无法正常使用
+  2. 选中(selected)、聚焦(focused)、禁用(disabled)等状态的样式需自行加上,你可以从props中获取到相对的boolean值
+  3. onMouseEnter需在wrapper dom上绑定,否则上下键盘操作时显示会有问题
+  4. 如果你的自定义 item 为 Select.Option,需要将 renderProps.onClick 透传给 Option 的 onSelect prop
+
+```jsx live=true
+import React from 'react';
+import { Select, Checkbox } from '@douyinfe/semi-ui';
+
+() => {
+    const renderOptionItem = renderProps => {
+        const {
+            disabled,
+            selected,
+            label,
+            value,
+            focused,
+            className,
+            style,
+            onMouseEnter,
+            onClick,
+            empty,
+            emptyContent,
+            ...rest
+        } = renderProps;
+        const optionCls = classNames({
+            ['custom-option-render']: true,
+            ['custom-option-render-focused']: focused,
+            ['custom-option-render-disabled']: disabled,
+            ['custom-option-render-selected']: selected,
+        });
+        // Notice:
+        // 1.props传入的style需在wrapper dom上进行消费,否则在虚拟化场景下会无法正常使用
+        // 2.选中(selected)、聚焦(focused)、禁用(disabled)等状态的样式需自行加上,你可以从props中获取到相对的boolean值
+        // 3.onMouseEnter需在wrapper dom上绑定,否则上下键盘操作时显示会有问题
+
+        return <div style={style} className={optionCls} onClick={() => onClick()} onMouseEnter={(e) => onMouseEnter()}>
+            <Checkbox checked={selected} />
+            <div className='option-right'>
+                {label}
+            </div>
+        </div>
+    };
+
+    const optionList = [
+      { value: 'tiktok', label: '抖音', otherKey:0 },
+      { value: 'hotsoon', label: '火山小视频', disabled: true, otherKey: 1 },
+      { value: 'jianying', label: '剪映', otherKey: 2 },
+      { value: 'toutiao', label: '今日头条', otherKey: 3 },
+    ];
+
+    return <>
+        <Select
+            filter
+            placeholder='单选'
+            dropdownClassName='components-select-demo-renderOptionItem'
+            optionList={optionList}
+            style={{ width: 180 }}
+            renderOptionItem={renderOptionItem}
+        />
+        <br/>
+        <br/>
+        <Select
+            filter
+            placeholder='多选'
+            multiple
+            dropdownClassName='components-select-demo-renderOptionItem'
+            optionList={optionList}
+            style={{ width: 320 }}
+            renderOptionItem={renderOptionItem}
+        />
+    </>
+};
+```
+
+```scss
+.components-select-demo-renderOptionItem {
+    .custom-option-render {
+        display: flex;
+        font-size: 14px;
+        line-height: 20px;
+        word-break: break-all;
+        padding-left: 12px;
+        padding-right: 12px;
+        padding-top: 8px;
+        padding-bottom: 8px;
+        color: var(--semi-color-text-0);
+        position: relative;
+        display: flex;
+        align-items: center;
+        cursor: pointer;
+        box-sizing: border-box;
+        .option-right {
+            margin-left: 8px;
+            display: inline-flex;
+            align-items: center;
+        }
+        &:active {
+            background-color: var(--semi-color-fill-1);
+        }
+        &-focused {
+            background-color: var(--semi-color-fill-0);
+        }
+        &-selected {
+            //font-weight: 700;
+        }
+        &-disabled {
+            color: var(--semi-color-disabled-text);
+            cursor: not-allowed;
+        }
+        &:first-of-type {
+            margin-top: 4px;
+        }
+        &:last-of-type {
+            margin-bottom: 4px;
+        }
+    }
+}
+```
+
+## API 参考
+
+### Select Props
+
+| 属性                     | 说明                                                                                                                                                                                                      | 类型                                  | 默认值                            |
+| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------------------------------- |
+| allowCreate              | 是否允许用户创建新条目,需配合 filter 使用                                                                                                                                                                | boolean                               | false                             |
+| arrowIcon            | 自定义右侧下拉箭头Icon,当showClear开关打开且当前有选中值时,hover会优先显示clear icon <br/>**v1.15.0 后提供**                                                                                                                                                                 | ReactNode     |                             |
+| autoAdjustOverflow       | 浮层被遮挡时是否自动调整方向(暂时仅支持竖直方向,且插入的父级为 body)<br/>**v0.27.0 后提供**                                                                                                             | boolean                               | true                              |
+| autoFocus                | 初始渲染时是否自动 focus                                                                                                                                                                                  | boolean                               | false                             |
+| className                | 类名                                                                                                                                                                                                      | string                                |                                   |
+| clickToHide              | 已展开时,点击选择框是否自动收起下拉列表 <br/>**v0.23.0 后提供**                                                                                                                                           | boolean                               | false                             |
+| defaultValue             | 初始选中的值                                                                                                                                                                                              | string\|number\|array                 |                                   |
+| defaultOpen              | 是否默认展开下拉列表                                                                                                                                                                                      | boolean                               | false                             |
+| disabled                 | 是否禁用                                                                                                                                                                                                  | boolean                               | false                             |
+| defaultActiveFirstOption | 是否默认高亮第一个选项(按回车可直接选中)                                                                                                                                                                | boolean                               | false                             |
+| dropdownClassName        | 弹出层的 className                                                                                                                                                                                        | string                                |                                   |
+| dropdownMatchSelectWidth | 下拉菜单最小宽度是否等于 Select                                                                                                                                                                           | boolean                               | true                              |
+| dropdownStyle            | 弹出层的样式                                                                                                                                                                                              | object                                |                                   |
+| emptyContent             | 无结果时展示的内容。设为 null 时,下拉列表将不展示                                                                                                                                                        | string\|ReactNode                     |                                   |
+| filter                   | 是否可搜索,默认为 false。传入 true 时,代表开启搜索并采用默认过滤策略(label 是否与 sugInput 匹配),传入值为函数时,会接收 sugInput, option 两个参数,当 option 符合筛选条件应返回 true,否则返回 false | boolean \|function(sugInput, option)                    | false                             |
+| getPopupContainer        | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative`                                                                                                                                                                     | function():HTMLElement                | () => document.body               |
+| innerTopSlot             | 渲染在弹出层顶部,在 optionList 内部的自定义 slot <br/>**v1.6.0 后提供**                                                                                                                              | ReactNode                             |                                   |
+| innerBottomSlot          | 渲染在弹出层底部,在 optionList 内部的自定义 slot                                                                                                                                                         | ReactNode                             |                                   |
+| insetLabel               | 同上,与 prefix 区别是 fontWeight 更大 <br/>**v0.23.0 后提供**                                                                                                                                             | ReactNode                             |                                   |
+| loading                  | 下拉列表是否展示加载动画                                                                                                                                                                                  | boolean                               | false                             |
+| maxTagCount              | 多选模式下,已选项超出 maxTagCount 时,后续选项会被渲染成+N 的形式                                                                                                                                        | number                                |                                   |
+| max                      | 最多可选几项,仅在多选模式下生效                                                                                                                                                                          | number                                |                                   |
+| maxHeight                | 下拉菜单中 `optionList` 的最大高度                                                                                                                                                                        | string\|number                        | 300                               |
+| multiple                 | 是否多选                                                                                                                                                                                                  | boolean                               | false                             |
+| outerTopSlot             | 渲染在弹出层顶部,与 optionList 平级的自定义 slot <br/>**v1.6.0 后提供**                                                                                                                              | ReactNode                             |                                   |
+| outerBottomSlot          | 渲染在弹出层底部,与 optionList 平级的自定义 slot                                                                                                                                                         | ReactNode                             |                                   |
+| onBlur                   | 失去焦点时的回调 <br/>**v0.32.0 后提供**                                                                                                                                                                   | function(event)                       |                                   |
+| onChange                 | 变化时回调函数                                                                                                                                                                                            | function(value:string\|number\|array) |                                   |
+| onCreate                 | allowCreate 为 true,创建备选项时的回调 <br/>**v0.23.0 后提供**                                                                                                                                            | function(option)                              |                                   |
+| onClear                  | 清除按钮的回调 <br/>**v0.34.0 后提供**                                                                                                                                                                     | function                              |                                   |
+| onChangeWithObject       | 是否将选中项 option 的其他属性作为回调。设为 true 时,onChange 的入参类型会从 string 变为 object: { value, label, ...rest }                                                                               | boolean                               | false                             |
+| onDropdownVisibleChange  | 下拉菜单展开/收起时的回调                                                                                                                                                                                 | function(visible:boolean)             |                                   |
+| onListScroll             | 候选项列表滚动时的回调                                                                                                                                                                                 | function(e)             |                                   |
+| onSearch                 | input 输入框内容发生改变时回调函数                                                                                                                                                                        | function(sugInput:string)             |                                   |
+| onSelect                 | 被选中时的回调<br/>**v0.26.0 后提供**                                                                                                                                                                      | function(value, option)               |                                   |
+| onDeselect               | 取消选中时的回调,仅在多选时有效<br/>**v0.26.0 后提供**                                                                                                                                                    | function(value, option)               |                                   |
+| onExceed                 | 当试图选择数超出 max 限制时的回调,仅在多选时生效 <br/> **v0.23.0** 后提供;入参在v1.16.0后提供                                                                                                                                   | function(option)                              |                                   |
+| onFocus                  | 获得焦点时的回调 <br/>**v0.32.0 后提供**                                                                                                                                                                   | function(event)                       |                                   |
+| optionList               | 可以通过该属性传入 Option,请确保数组内每个元素都具备 label、value 属性                                                                                                                                    | array(\[{value, label}\])             |                                   |
+| placeholder              | 选择框默认文字                                                                                                                                                                                            | ReactNode                                |                                   |
+| position                 | 菜单展开的位置,可选项同Tooltip position                                                                                                                  | string                                | 'bottomLeft'                      |
+| prefix                   | 选择框的前缀标签 <br/>**v0.23.0 后提供**                                                                                                                                                                   | ReactNode                             |                                   |
+| renderCreateItem         | allowCreate 为 true 时,可自定义创建标签的渲染 <br/>**v0.23.0 后提供**                                                                                                                                     | function(inputValue:string)           | inputValue => '创建' + inputValue |
+| renderSelectedItem       | 通过 renderSelectedItem 自定义选择框中已选项标签的渲染<br/>**v0.23.0 后提供**                                                                                                                              | function(option)                      |                                   |
+| renderOptionItem         | 通过 renderOptionItem 完全自定义下拉列表中候选项的渲染<br/>**v1.10.0 后提供**                                                                                                                              | function(props) 入参详见Demo                      |                                   |
+| remote                   | 是否开启远程搜索,当 remote 为 true 时,input 内容改变后不会进行本地筛选匹配<br/>**v0.24.0 后提供**                                                                                                        | boolean                               | false                             |
+| size                     | 大小,可选值 `default`/`small`/`large`                                                                                                                                                                    | string                                | 'default'                         |
+| style                    | 样式                                                                                                                                                                                                      | object                                |                                   |
+| suffix                   | 选择框的后缀标签 <br/>**v0.23.0 后提供**                                                                                                                                                                   | ReactNode                             |                                   |
+| showClear                | 是否展示清除按钮 <br/>**v0.23.0 后提供**                                                                                                                                                                   | boolean                               | false                             |
+| showArrow                | 是否展示下拉箭头 <br/>**v0.23.0 后提供**                                                                                                                                                                   | boolean                               | true                              |
+| spacing                  | 浮层与选择器的距离 <br/>**v0.29.0 后提供**                                                                                                                                                                 | number                                | 4                                 |
+| triggerRender            | 自定义触发器渲染 <br/>**v0.34.0 后提供**                                                                                                                                                                   | function                              |                                   |
+| value                    | 当前选中的的值,传入该值时将作为受控组件,配合 `onChange` 使用                                                                                                                                             | string\|number\|array                 |                                   |
+| validateStatus           | 校验结果,可选`warning`、`error`、 `default`(只影响样式背景色)                                                                                                                                          | string                                | 'default'                         |
+| virtualize               | 列表虚拟化,用于大量节点的情况优化性能表现,由 height, width, itemSize 组成<br/>**v0.37.0 后提供**                                                                                                         | object                                |                                   |
+| zIndex                   | 弹层的 zIndex                                                                                                                                                                                             | number                                | 1030                              |
+
+
+### Option Props
+
+---
+
+> **不同 Option 的 label 必须唯一,不允许重复**
+
+| 属性      | 说明                                                               | 类型           | 默认值 |
+| --------- | ------------------------------------------------------------------ | -------------- | ------ |
+| className | 样式类名                                                           | string         |        |
+| disabled  | 是否禁用                                                           | boolean        | false  |
+| label     | 展示的文本。渲染时优先取 label,若无则取 children、value,依次降级 | string\|ReactNode        |        |
+| showTick  | 被选中时,展示 √ 的 Icon                                           | boolean        | true   |
+| style     | 样式                                                               | object         |        |
+| value     | 属性值                                                             | string\|number |        |
+
+### OptGroup Props
+
+---
+
+| 属性      | 说明       | 类型      | 版本 |
+| --------- | ---------- | --------- | ------ |
+| className | 样式类名   | string    |v0.31.0        |
+| label     | 展示的文本 | ReactNode |v0.31.0        |
+| style     | 样式       | object    | v0.31.0       |
+
+### Method()
+
+绑定在ref上的方法,可以通过ref调用实现某些特殊交互
+
+| 方法  | 说明                       | 版本 |
+| ----- | -------------------------- | ---- |
+| close | 调用时可以手动关闭下拉列表 |v0.34.0 |
+| open  | 调用时可以手动展开下拉列表 |v0.34.0|
+| focus | 调用时可以手动聚焦 | v1.11.0 |
+| clearInput | 调用时可以手动清空input搜索框的值 | v1.18.0 |
+| deselectAll | 调用时可以手动清空所有已选项 | v1.18.0 |
+| selectAll | 调用时可以选中所有Option | v1.18.0 |
+
+## 设计变量
+<DesignToken/>
+
+## FAQ
+
+-   **可搜索的 Select,使用远程数据动态更新`optionList`,为什么在异步请求完成之前有时候会出现暂无数据?**  
+     请检查是否设置了`remote={true}`,不设置 remote 的情况下,默认会将 input 框输入值与当前的 optionList 进行一次对比筛选,如果无匹配时,就会显示暂无数据。  
+     可以通过设置 remote 为 true 关闭对本地当前数据的匹配筛选。
+
+-   **使用jsx方式声明Option,label为i18n后的内容,切换locale后未能重新渲染**
+    -   children jsx方式声明Options时,由于是reactNode,不可能用deepEqual来做对比判断内容是否有更新(性能消耗过大),所以会收集children reactNode的key,当key不变时,就认为Options都没有发生变化,不会走重新收集数据的流程。你可以将locale也作为Option key的一部分。
+    -   使用optionList方式传入,也可以解决问题。因为对于object形式传入,key相对有限,Select内部会使用isEqual来判断是否发生变化
+
+-   **使用jsx方式声明Option,动态切换disabled属性后未能重新渲染**
+    -   原因同上,你可以重新给Option设定不同的key值,或者使用optionList方式声明候选项
+
+-   **Select会自动限制下拉菜单的宽度吗?**
+    - 会给minWidth,但不会写死width。如果有需要的话,可以自己通过dropdownStyle来添加。      
+
+-   **设置allowCreate后,动态更新optionList或者children不生效**
+    - allowCreate主要用于本地创建的场景,开启该项后,相当于强接管了optionList / children,不会再响应外部对这两类值的更新。
+
+-   **为什么Semi的Select要求label必须唯一,而不是value必须唯一?**
+    - 首先,我们一定需要一个唯一标识符用来做选中的判断。几乎所有UI库,对Select.Option使用时,最低要求都只会要求传入label、value两个值,而不会再单独要求传入一个key(过于繁琐)。Semi延续了这个设定
+    - 那么为什么在semi的select中是label而不是value呢?
+      - option的label是用户感知的内容。从交互的角度而言,如果出现两个展示上一模一样的选项,对用户感知而言,他们看上去是一样的,无法进行区分,但选中的作用又不一样(例如一个value为0,另一个为1),是不合理的。(用户第一反应往往是重复了,可能出bug了)
+      - label唯一、value重复,在日常使用中会更为常见。例如,一个根据app名称选择公司id的选择器,value是app对应的公司id,label是app的名称。
+        ```
+          <Select placeholder='choose company by app'>
+            <Option label='vigo' value='bytedance' />
+            <Option label='tiktok' value='bytedance' />
+          </Select>
+        ```
+
+<!-- ## 相关物料
+
+```material
+3,4,44,54,58,62,72
+``` -->

+ 260 - 0
content/input/slider/index-en-US.md

@@ -0,0 +1,260 @@
+---
+localeCode: en-US
+order: 26
+category: Input
+title:  Slider
+subTitle: Slider
+icon: doc-slider
+brief: Slider is used to help users quickly enter a numeric value or range.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Slider } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+You can set `range={true}` to allow slider slide from both sides.
+
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <div>
+        <div>Default</div>
+        <Slider showBoundary={true}></Slider>
+    </div>
+    <br/>
+    <br/>
+    <div>
+        <div>Range</div>
+        <Slider defaultValue={[20, 60]} range></Slider>
+    </div>
+    <br/>
+    <br/>
+    <div>
+        <div>Disabled</div>
+        <Slider defaultValue={40} disabled></Slider>
+    </div>
+  </div>
+)
+```
+
+### With Input
+
+Synchronize slider with input value.
+
+```jsx live=true
+import React from 'react';
+import { Slider, InputNumber } from '@douyinfe/semi-ui';
+
+class InputSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: 10 };
+    this.getSliderValue = this.getSliderValue.bind(this);
+  }
+
+  getSliderValue(value) {
+      this.setState({ value: value / 1 });
+  }
+
+  render() {
+    const { value } = this.state
+    return (
+      <div>
+          <div style={{ width: 320, marginRight: 15 }}>
+              <Slider step={1} value={value} onChange={(value) => (this.getSliderValue(value))} ></Slider>
+          </div>
+          <InputNumber onChange={(v) => this.getSliderValue(v)} style={{width: 100}} value={value} />
+      </div>
+    );
+  }
+}
+```
+
+### Tooltip
+
+You can use `tipFormatter` to format Tooltip content or set `tipFormatter={null}`to hide Tooltip.
+
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <Slider tipFormatter={v => (`${v}%`)} />
+    <br/>
+    <br/>
+    <Slider tipFormatter={null} />
+  </div>
+)
+```
+
+### With Tag
+
+Use `marks` to label measures on sliders.
+
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <div>step=10</div>
+    <Slider step={10} marks={{ 0: '0', 10: '10', 20: '20', 30: '30', 40: '40', 50: '50', 100: '100' }} defaultValue={[10, 100]} range={true}></Slider>
+    <br/>
+    <br/>
+    <div>step=0.1</div>
+    <Slider step={0.1} marks={{ 0.1: '0.1', 0.2: '0.2', 0.3: '0.3', 0.4: '0.4', 0.5: '0.5' }} min={0} max={1} defaultValue={[0.1, 0.5]} range={true}></Slider>
+    <br/>
+    <br/>
+    <div>Marks</div>
+    <Slider marks={{ 20: '20c', 40: '40c' }} defaultValue={[0, 100]} range={true} ></Slider>
+    <br/>
+    <br/>
+    <div>Inclued</div>
+    <Slider marks={{ 20: '20c', 40: '40c' }} included={false} defaultValue={[0, 100]} range={true}></Slider>
+  </div>
+)
+```
+
+
+### Segmented Background
+To create a slider with segmented background, you could use css property `linear-gradient` for `railStyle` along with `onChange` to change background dynamically。
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+class SegSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: [20, 60] };
+    this.changeValue = this.changeValue.bind(this);
+    this.getRailStyle = this.getRailStyle.bind(this);
+  }
+
+  changeValue(value) {
+    this.setState({ value });
+  }
+
+  getRailStyle(range) {
+    // color of second segment inherits from .semi-slider-track
+    const color = ['var(--semi-color-danger)', 'transparent', 'var(--semi-color-success)'];
+    const gradientPos = this.state.value.map(val => 
+      ((val - range[0]) / (range[1] - range[0])).toFixed(2) * 100
+    );
+    const style = {
+      background: `linear-gradient(to right, ${color[0]} ${gradientPos[0]}%, ${color[1]} ${gradientPos[0]}%, ${color[1]} ${gradientPos[1]}%, ${color[2]} ${gradientPos[1]}%)`
+    }
+    return style;
+  }
+
+  render() {
+    const range = [10, 100];
+    const railStyle = this.getRailStyle(range);
+    return (
+        <Slider
+          range
+          min={range[0]}
+          max={range[1]}
+          onChange={this.changeValue}
+          railStyle={railStyle}
+          defaultValue={this.state.value}
+        />
+    );
+  }
+}
+```
+
+### Controlled Component
+
+You can use `value` along with `onChange` property if you want to use Slider as a controlled component.
+
+```jsx live=true
+import React from 'react';
+import { Slider, Button } from '@douyinfe/semi-ui';
+
+class ControllSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: 10 };
+    this.changeValue = this.changeValue.bind(this);
+  }
+
+  changeValue() {
+    this.setState({ value: this.state.value + 10 });
+  }
+
+  render() {
+    return (
+      <div>
+        <Button onClick={this.changeValue} style={{ marginRight: 20 }}>Click to change value</Button>
+        <br/>
+        <br/>
+        <Slider value={this.state.value}></Slider>
+      </div>
+    );
+  }
+}
+```
+
+### Vertical
+
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical></Slider>
+      </div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical verticalReverse></Slider>
+      </div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical range defaultValue={[20, 60]}></Slider>
+      </div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical verticalReverse range defaultValue={[20, 60]}></Slider>
+      </div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical range marks={{ 20: '20c', 40: '40c' }} step={10} defaultValue={[20, 60]}></Slider>
+      </div>
+      <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+          <Slider vertical verticalReverse range marks={{ 20: '20c', 40: '40c' }} step={10} defaultValue={[20, 60]}></Slider>
+      </div>
+  </div>
+)
+```
+
+## API Reference
+
+| Property       | Instructions                                                                               | type          | Default | Version | 
+| -------------- | ------------------------------------------------------------------------------------------ | ------------- | ------- |------ |
+| defaultValue   | Default value                                                                              | number \| number[] | 0       |- |
+| disabled       | Disable slider                                                                             | boolean       | false   |- |
+| included       | Takes effect when `marks` is not null, true means containment and false means coordinative | boolean       | true    |- |
+| marks          | Tick mark of Slider, type of key must be number, and must in closed interval [min, max]    | Record<number, string \>        | -       |- |
+| max            | Maximum value of the slider.                                                               | number        | 100     |- |
+| min            | Minimum value of the slider.                                                               | number        | 0       |- |
+| railStyle | Style for slide rail | CSSProperties | - |0.31.0|
+| range          | Toggle whether it is allow to move slider from both sides                                  | boolean       | false   |- |
+| step           | Increment between successive values                                                        | number        | 1       |- |
+| tipFormatter   | Format Tooltip content, by default display current value                                   | (value: string \| number \| boolean \| (string \| number \| boolean)[]) => any      | v => v  |- |
+| tooltipVisible | Toggle whether to display tooltip all the time                                             | boolean       | -       |- |
+| value          | Set current value, used in controlled component                                            | number \| number[] |         |- |
+| vertical       | Toggle whether to display slider vertically                                                | boolean       | false   |- |
+| verticalReverse | Vertical but reverse direction >=1.29.0| boolean | false |-|
+| onAfterChange  | Triggered when onmouseup is invoked, passed in current value as params                     | (value: number \| number[]) => void      | -       |- |
+| onChange       | Callback function when slider value changes                                                | (value: number \| number[]) => void      | -       |- |
+
+## Design Tokens
+<DesignToken/>

+ 244 - 0
content/input/slider/index.md

@@ -0,0 +1,244 @@
+---
+localeCode: zh-CN
+order: 26
+category: 输入类
+title:  Slider 滑动选择器
+icon: doc-slider
+brief: 滑动选择器帮助用户快速输入连续或离散的数值,或由这些数值组成的一段数值范围。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Slider } from '@douyinfe/semi-ui';
+```
+### 基本用法
+基本滑动条。当 `range` 为 `true` 时,支持两侧滑动。当 `disabled` 为 `true` 时,滑块处于不可用状态。
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <div>
+        <div>Default</div>
+        <Slider showBoundary={true}></Slider>
+    </div>
+    <br/>
+    <br/>
+    <div>
+        <div>Range</div>
+        <Slider defaultValue={[20, 60]} range></Slider>
+    </div>
+    <br/>
+    <br/>
+    <div>
+        <div>Disabled</div>
+        <Slider defaultValue={40} disabled></Slider>
+    </div>
+  </div>
+)
+```
+
+### 带输入框的
+滑动条的滑块和输入框组件保持同步。
+```jsx live=true
+import React from 'react';
+import { Slider, InputNumber } from '@douyinfe/semi-ui';
+
+class InputSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: 10 };
+    this.getSliderValue = this.getSliderValue.bind(this);
+  }
+
+  getSliderValue(value) {
+      this.setState({ value: value / 1 }); 
+  }
+
+  render() {
+    const { value } = this.state
+    return (
+      <div>
+          <div style={{ width: 320, marginRight: 15 }}>
+              <Slider step={1} value={value} onChange={(value) => (this.getSliderValue(value))} ></Slider>
+          </div>
+          <InputNumber onChange={(v) => this.getSliderValue(v)} style={{width: 100}} value={value} />
+      </div>
+    );
+  }
+}
+```
+
+### 自定义提示
+使用 `tipFormatter` 可以设置 Tooltip 的显示的格式。设置 `tipFormatter={null}`,则隐藏 Tooltip。
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <Slider tipFormatter={v => (`${v}%`)} />
+    <br/>
+    <br/>
+    <Slider tipFormatter={null} />
+  </div>
+)
+```
+
+### 带标签的
+使用 `marks` 属性标注滑块的刻度,使用 `value` / `defaultValue` 指定滑块位置。
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+    <div>step=10</div>
+    <Slider step={10} marks={{ 0: '0', 10: '10', 20: '20', 30: '30', 40: '40', 50: '50', 100: '100' }} defaultValue={[10, 100]} range={true}></Slider>
+    <br/>
+    <br/>
+    <div>step=0.1</div>
+    <Slider step={0.1} marks={{ 0.1: '0.1', 0.2: '0.2', 0.3: '0.3', 0.4: '0.4', 0.5: '0.5' }} min={0} max={1} defaultValue={[0.1, 0.5]} range={true}></Slider>
+    <br/>
+    <br/>
+    <div>Marks</div>
+    <Slider marks={{ 20: '20c', 40: '40c' }} defaultValue={[0, 100]} range={true} ></Slider>
+    <br/>
+    <br/>
+    <div>Inclued</div>
+    <Slider marks={{ 20: '20c', 40: '40c' }} included={false} defaultValue={[0, 100]} range={true}></Slider>
+  </div>
+)
+```
+
+### 分段背景
+通过使用 `linear-gradient` 及 `railStyle` ,配合 onChange 可以实现动态的分段背景效果。
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+class SegSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: [20, 60] };
+    this.changeValue = this.changeValue.bind(this);
+    this.getRailStyle = this.getRailStyle.bind(this);
+  }
+
+  changeValue(value) {
+    this.setState({ value });
+  }
+
+  getRailStyle(range) {
+    // color of second segment inherits from .semi-slider-track
+    const color = ['var(--semi-color-danger)', 'transparent', 'var(--semi-color-success)'];
+    const gradientPos = this.state.value.map(val => 
+      ((val - range[0]) / (range[1] - range[0])).toFixed(2) * 100
+    );
+    const style = {
+      background: `linear-gradient(to right, ${color[0]} ${gradientPos[0]}%, ${color[1]} ${gradientPos[0]}%, ${color[1]} ${gradientPos[1]}%, ${color[2]} ${gradientPos[1]}%)`
+    }
+    return style;
+  }
+
+  render() {
+    const range = [10, 100];
+    const railStyle = this.getRailStyle(range);
+    return (
+        <Slider
+          range
+          min={range[0]}
+          max={range[1]}
+          onChange={this.changeValue}
+          railStyle={railStyle}
+          defaultValue={this.state.value}
+        />
+    );
+  }
+}
+```
+
+### 受控组件
+滑块位置即 `Slider` 的值由 value 控制,配合 onChange 使用。
+```jsx live=true hideInDSM
+import React from 'react';
+import { Slider, Button } from '@douyinfe/semi-ui';
+
+class ControllSlider extends React.Component {
+  constructor(props) {
+    super();
+    this.state = { value: 10 };
+    this.changeValue = this.changeValue.bind(this);
+  }
+
+  changeValue() {
+    this.setState({ value: this.state.value + 10 });
+  }
+
+  render() {
+    return (
+      <div>
+        <Button onClick={this.changeValue} style={{ marginRight: 20 }}>点击改变value值</Button>
+        <br/>
+        <br/>
+        <Slider value={this.state.value}></Slider>
+      </div>
+    );
+  }
+}
+```
+
+### 垂直
+```jsx live=true
+import React from 'react';
+import { Slider } from '@douyinfe/semi-ui';
+
+<div>
+  <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical></Slider>
+  </div>
+  <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical verticalReverse></Slider>
+  </div>
+  <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical range defaultValue={[20, 60]}></Slider>
+  </div>
+  <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical verticalReverse range defaultValue={[20, 60]}></Slider>
+  </div>
+  <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical range marks={{ 20: '20c', 40: '40c' }} step={10} defaultValue={[20, 60]}></Slider>
+  </div>
+    <div style={{height: 300, marginLeft: 30, marginTop: 10, paddingRight: 30, display: 'inline-block'}}>
+      <Slider vertical verticalReverse range marks={{ 20: '20c', 40: '40c' }} step={10} defaultValue={[20, 60]}></Slider>
+    </div>
+</div>
+```
+
+## API参考
+| 属性  | 说明        | 类型   | 默认值 | 版本 | 
+|-------|-------------|-----------------|--------|-------|
+| defaultValue | 设置初始取值 | number \| number[] | 0 |-|
+| disabled | 滑块是否禁用 | boolean | false |-|
+| included | `marks` 不为空对象时有效,值为 true 时表示值为包含关系,false 表示并列 | boolean | true |-|
+| marks | 刻度,key 的类型必须为 `number` 且取值在闭区间 \[min, max] 内 | Record<number, string \> | 无 |-|
+| max | 最大值 | number | 100 |-|
+| min | 最小值 | number | 0 |-|
+| railStyle | 滑块轨道的样式 | CSSProperties | - |0.31.0|
+| range | 是否支持两边同时可滑动 | boolean | false |-|
+| step | 步长 | number | 1 |-|
+| tipFormatter | 设置Tooltip的展示格式,默认显示当前选值  | (value: string \| number \| boolean \| (string \| number \| boolean)[]) => any | v => v |-|
+| tooltipVisible | 是否始终显示Tooltip | boolean | 无 |-|
+| value | 设置当前取值 | number \| number[] |  |-|
+| vertical | 是否设置方向为垂直 | boolean | false |-|
+| verticalReverse | 反转垂直方向,即上大下小 >=1.29.0| boolean | false |-|
+| onAfterChange | 与 `onmouseup` 触发时机一致,把当前值作为参数传入 | (value: number \| number[]) => void | 无 |-|
+| onChange | 当 Slider 的值发生改变时的回调 | (value: number \| number[]) => void | 无 |-|
+
+## 设计变量
+<DesignToken/>

+ 189 - 0
content/input/switch/index-en-US.md

@@ -0,0 +1,189 @@
+---
+localeCode: en-US
+order: 27
+category: Input
+title:  Switch
+subTitle: Switch
+icon: doc-switch
+width: 60%
+brief: Switch is an interactive form used to switch two mutually exclusive states.
+---
+
+## Demos
+### How to import
+
+```jsx import
+import { Switch } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+      <Switch onChange={(v, e) => console.log(v)}>
+      </Switch>
+      <br/>
+      <Switch defaultChecked={true} onChange={(v, e) => console.log(v)}>
+      </Switch>
+  </div>
+)
+```
+
+### Size
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+        <Switch size='small'></Switch>
+        <Switch defaultChecked={true} size='small'></Switch>
+        <Switch size='small' loading/>
+        <Switch size='small' loading defaultChecked={true} />
+        <br/><br/>
+        <Switch></Switch>
+        <Switch defaultChecked={true}></Switch>
+        <Switch loading />
+        <Switch loading defaultChecked={true} />
+        <br/><br/>
+        <Switch size='large'></Switch>
+        <Switch defaultChecked={true} size='large'></Switch>
+        <Switch size='large' loading/>
+        <Switch size='large' loading defaultChecked={true} />
+  </div>
+)
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+        <Switch disabled></Switch>
+        <br/>
+        <Switch disabled checked={true}></Switch>
+  </div>
+)
+```
+
+### With text
+
+Can pass `checkedText` with `uncheckedText` Text when setting the switch  
+The long text is recommended to be placed directly on the outside.  
+Note: This does not work with the smallest switch (size = 'small')
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Switch checkedText='on' uncheckedText='off' />
+        <Switch checkedText='|' uncheckedText='〇' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch defaultChecked checkedText='on' uncheckedText='off' />
+        <Switch defaultChecked checkedText='|' uncheckedText='〇' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch checkedText='on' uncheckedText='off' size='large' />
+        <Switch checkedText='|' uncheckedText='〇' size='large' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch defaultChecked checkedText='on' uncheckedText='off' size='large' />
+        <Switch defaultChecked checkedText='|' uncheckedText='〇' size='large' style={{marginLeft:5}}/>
+    </div>
+)
+```
+
+Compared to setting the embedded text through chekedText and uncheckedText, we recommend placing the text description outside the Switch
+```jsx live=true
+import React, { useState } from 'react';
+import { Switch, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const [open, setOpen] = useState();
+    const { Title } = Typography;
+    return (
+        <div style={{display:'flex', alignItems: 'center'}}>
+          <Title heading={6} style={{margin: 8}}>{open?'Open':'Closed'}</Title>
+          <Switch checked={open} onChange={setOpen}/>
+        </div>
+    )
+}
+```
+
+### Controlled component
+
+Whether the component is selected depends entirely on the incoming checkced value, used with `onChange`
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            checked: true,
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(checked) {
+        this.setState({ checked });
+    }
+    render() {
+        return (
+            <>
+            <Switch
+                checked={this.state.checked}
+                onChange={this.onChange}>
+            </Switch>
+            </>
+        )
+    }
+}
+```
+
+### loading
+
+version: >= 1.29.0
+
+You can turn on the loading state by setting loading="true".
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Switch loading />
+        <br />
+        <Switch loading defaultChecked={true} />
+    </div>
+)
+```
+
+## API reference
+
+| Properties     | Instructions                                              | Type                        | Default   | version|
+| -------------- | --------------------------------------------------------- | --------------------------- | --------- | ------ |
+| className      | The CSS class name of the wrapper element                 | string                      |           ||
+| checked        | Indicates whether currently selected, used with onchange  | boolean                     | false     ||
+| checkedText    | Content displayed when open, invalid when size is small   | React Node                  |           |0.25.0|
+| defaultChecked | Whether selected when component mounted                   | boolean                     | false     ||
+| disabled       | If true, the switch will be disabled.                     | boolean                     | false     ||
+| loading        | Turn on loading status                                    | boolean                     | false     |1.29.0|
+| onChange       | Callback function when changing                           | function (checked: boolean) |           ||
+| onMouseEnter   | A callback when the mouse moves in                        | function ()                 |           ||
+| onMouseLeave   | A callback when the mouse moves out                       | function ()                 |           ||
+| size           | Size, optional value `large`, `default`, `small`          | string                      | 'default' ||
+| style          | Inline style                                              | object                      | {}        ||
+| uncheckedText  | Content displayed when closed, invalid when size is small | React Node                  |           |0.25.0|
+
+## Design Tokens
+<DesignToken/>

+ 188 - 0
content/input/switch/index.md

@@ -0,0 +1,188 @@
+---
+localeCode: zh-CN
+order: 27
+category: 输入类
+title:  Switch 开关
+icon: doc-switch
+width: 60%
+brief: 开关是用于切换两种互斥状态的交互形式
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Switch } from '@douyinfe/semi-ui';
+```
+### 基本
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+      <Switch onChange={(v, e) => console.log(v)}>
+      </Switch>
+      <br/>
+      <Switch defaultChecked={true} onChange={(v, e) => console.log(v)}>
+      </Switch>
+  </div>
+)
+```
+
+### 尺寸
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+        <Switch size='small'></Switch>
+        <Switch defaultChecked={true} size='small'></Switch>
+        <Switch size='small' loading/>
+        <Switch size='small' loading defaultChecked={true} />
+        <br/><br/>
+        <Switch></Switch>
+        <Switch defaultChecked={true}></Switch>
+        <Switch loading />
+        <Switch loading defaultChecked={true} />
+        <br/><br/>
+        <Switch size='large'></Switch>
+        <Switch defaultChecked={true} size='large'></Switch>
+        <Switch size='large' loading/>
+        <Switch size='large' loading defaultChecked={true} />
+  </div>
+)
+```
+
+### 不可用
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+  <div>
+        <Switch disabled></Switch>
+        <br/>
+        <Switch disabled checked={true}></Switch>
+  </div>
+)
+```
+
+### 带文本
+
+可以通过 `checkedText` 与 `uncheckedText` 设置开关时的文本  
+注意:此项功能在最小的开关(即 size='small'时)无效  
+
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Switch checkedText='开' uncheckedText='关' />
+        <Switch checkedText='|' uncheckedText='〇' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch defaultChecked checkedText='开' uncheckedText='关' />
+        <Switch defaultChecked checkedText='|' uncheckedText='〇' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch checkedText='开' uncheckedText='关' size='large' />
+        <Switch checkedText='|' uncheckedText='〇' size='large' style={{marginLeft:5}}/>
+        <br/><br/>
+        <Switch defaultChecked checkedText='开' uncheckedText='关' size='large' />
+        <Switch defaultChecked checkedText='|' uncheckedText='〇' size='large' style={{marginLeft:5}}/>
+    </div>
+)
+```
+
+相比于通过chekedText与uncheckedText设置内嵌的文本,我们更推荐将文本说明放置在Switch外部
+```jsx live=true
+import React, { useState } from 'react';
+import { Switch, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const [open, setOpen] = useState();
+    const { Title } = Typography;
+    return (
+        <div style={{display:'flex', alignItems: 'center'}}>
+          <Title heading={6} style={{margin: 8}}>{open?'已开启':'已关闭'}</Title>
+          <Switch checked={open} onChange={setOpen}/>
+        </div>
+    )
+}
+```
+
+### 受控组件
+
+组件是否选中完全取决于传入的 checkced 值,配合 onChange 回调函数使用
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            checked: true,
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(checked) {
+        this.setState({ checked });
+    }
+    render() {
+        return (
+            <>
+            <Switch
+                checked={this.state.checked}
+                onChange={this.onChange}>
+            </Switch>
+            </>
+        )
+    }
+}
+```
+
+### 加载中
+
+version: >= 1.29.0
+
+可以通过设置 loading="true" 开启加载中状态。
+
+```jsx live=true
+import React from 'react';
+import { Switch } from '@douyinfe/semi-ui';
+
+  <div>
+        <Switch loading />
+        <br />
+        <Switch loading defaultChecked={true} />
+  </div>
+```
+
+## API 参考
+
+| 属性           | 说明                                     | 类型                      | 默认值    |版本|
+| -------------- | ---------------------------------------- | ------------------------- | --------- |--------- |
+| className      | 类名                                     | string                    |           |
+| checked        | 指示当前是否选中,配合 onChange 使用      | boolean                   | false     ||
+| checkedText    | 打开时展示的内容, size为small时无效 | ReactNode                 |           |0.25.0|
+| defaultChecked | 初始是否选中                             | boolean                   | false     ||
+| disabled       | 是否禁用                                 | boolean                   | false     ||
+| loading        | 设置加载状态                                 | boolean                   | false     |1.29.0|
+| onChange       | 变化时回调函数                           | function(checked:boolean) |           ||
+| onMouseEnter   | 鼠标移入时回调                        | function()                |           ||
+| onMouseLeave   | 鼠标移出时回调                        | function()                |           ||
+| size           | 尺寸,可选值`large`,`default`,`small`     | string                    | 'default' ||
+| style           | 内联样式     | object                    | ||
+| uncheckedText  | 关闭时展示的内容, size为small时无效 | ReactNode                 |           |0.25.0|
+
+## 设计变量
+<DesignToken/>

+ 461 - 0
content/input/taginput/index-en-US.md

@@ -0,0 +1,461 @@
+---
+localeCode: en-US
+order: 28
+category: Input
+title: TagInput
+subTitle: TagInput
+icon: doc-tagInput
+brief: Taginput is a input component that can add content as a tag.
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { TagInput } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+After pressing the Enter key, the input will add value as a tag. If the tag content is an empty string or pure space, it will be filtered.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        defaultValue={['Tiktok','Hotsoon','Pipixia']}
+        placeholder='Please enter...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### Batch Add
+
+You can use `separator` to set the separator to achieve batch input, and its default value is a comma. After version 1.29.0, multiple separators are supported in string[] format.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput 
+            separator='-' 
+            placeholder='Use `-` for batch input'
+            onChange={v => console.log(v)}
+        />
+        <br/><br/>
+        <TagInput 
+            separator={['-', '/', '|', '++']}
+            placeholder='Support multiple separators for batch input'
+            onChange={v => console.log(v)}
+        />
+    </>
+)
+```
+
+### Batch Remove
+
+You can also use `showClear` to set whether to support one-click deletion of all tags and input.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        showClear 
+        defaultValue={['Tiktok','Hotsoon']} 
+        placeholder='Please enter...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        disabled 
+        showClear 
+        defaultValue={['Tiktok','Hotsoon','Pipixia']} 
+        placeholder='Please enter...'
+    />
+)
+```
+
+### Size
+
+Use `size` to set the size of the TagInput, optional: `small`, `default`, `large`.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput size='small' placeholder='small'/>
+        <br/><br/>
+        <TagInput placeholder='default'/>
+        <br/><br/>
+        <TagInput size='large' placeholder='large'/>
+    </>
+)
+```
+
+### Different validate status
+
+validateStatus: `default`, `warning`, `error`.
+
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput placeholder='default'/>
+        <br/><br/>
+        <TagInput placeholder='warning' validateStatus='warning'/>
+        <br/><br/>
+        <TagInput placeholder='error' validateStatus='error'/>
+    </>
+)
+``` 
+
+### Prefix / Suffix
+
+You can pass the input box prefix through `prefix`, the input box suffix through `suffix`, for text or React Node.  
+The left and right padding is automatically brought when the content passed in by prefix and reactix is text or Icon. If it is a custom ReactNode, the left and right padding is 0.If necessary, you can set it in the reactNode you passed in.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
+
+() => (
+    <>
+        <TagInput prefix={<IconVigoLogo />} showClear/>
+        <br/><br/>
+        <TagInput  prefix="Prefix" showClear/>
+        <br/><br/>
+        <TagInput suffix={<IconGift />}/>
+        <br/><br/>
+        <TagInput  suffix="Suffix" showClear/>
+    </>
+)
+``` 
+
+### Allow Duplicates
+
+You can use `allowDuplicates` to set whether to allow the creation of the same tag.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        allowDuplicates={false}
+        defaultValue={['Tiktok','Hotsoon','Pipixia']} 
+        placeholder='Please enter...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### Autocomplete
+
+You can use `addOnBlur` to set whether the current input value is automatically created as a tag when the blur event is triggered.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        addOnBlur={true}
+        defaultValue={['Tiktok','Hotsoon','Pipixia']} 
+        placeholder='Please enter...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### Limits
+
+You can use `max` to limit the number of tags. The `onExceed()` callback will be invoked when the limit is exceeded.
+
+You can use `maxLength` to limit the maximum length of a single tag, and the `onInputExceed()` callback will be invoked when this value is exceeded.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput 
+            max={3} 
+            placeholder='max = 3' 
+            onChange={v => console.log(v)}
+            onExceed={v => {
+                Toast.warning('Exceeds max');
+                console.log(v);
+            }}
+        />
+        <TagInput 
+            maxLength={5} 
+            placeholder='maxLength = 5'  
+            style={{marginTop:12}}
+            onChange={v => console.log(v)}
+            onInputExceed={v => {
+                Toast.warning('Exceeds maxLength');
+                console.log(v);
+            }} 
+        />
+    </>
+)
+```
+
+### Limit the number of tags displayed
+
+You can use `maxTagCount` to limit the number of tags displayed, and the excess will be displayed as +N. You can use `showRestTagsPopover` to set whether hover +N displays Popover after `maxTagCount` is exceeded, and you can configure Popover in the `restTagsPopoverProps` property.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        maxTagCount={2}
+        showRestTagsPopover={true}
+        restTagsPopoverProps={{ position: 'top' }}
+        defaultValue={['Tiktok','Hotsoon','Pipixia']} 
+    />
+)
+```
+
+### Controlled Tag
+
+You can use `value` to set tags, and use `onChange` to achieve control of the tags.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            value: ['tiktok']
+        };
+    }
+    onChange(value) {
+        this.setState({ value });
+    }
+    render() {
+        return (
+            <TagInput
+                value={this.state.value}
+                onChange={value => {this.onChange(value);}}
+            />
+        )
+    }
+}
+```
+
+### Controlled Input
+
+You can use `inputValue` to set input box, and use `onInputChange` to control the input content.
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            value: 'tiktok'
+        }
+    }
+    handleInputChange(value, event) {
+      this.setState({ value });
+    }
+    render() {
+        return (
+            <TagInput
+                inputValue={this.state.value}
+                onInputChange={(v,e) => this.handleInputChange(v,e)}
+            />
+        )
+    }
+}
+```
+
+### Callback
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        defaultValue={['Tiktok','Hotsoon','Pipixia']} 
+        showClear 
+        onFocus={e =>{console.log(`onFocus`);}} 
+        onBlur={e=>{console.log(`onBlur`);}} 
+        onChange={tag=>{console.log(`onChange :${tag}`);}} 
+        onAdd={tag=>{console.log(`onAdd :${tag}`);}} 
+        onRemove={(v,i)=>{console.log(`onRemove :${v}, index:${i}`);}} 
+        onInputChange={(input,e)=>{console.log(`onInputChange :${input}`);}} 
+    />
+)
+```
+
+### Focus Management
+
+You can use the `blur()` and `focus()` methods to manage the focus.
+
+```jsx live=true
+import React from 'react';
+import { TagInput, Button } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.ref = React.createRef();
+        this.handleTagInputFocus=this.handleTagInputFocus.bind(this);
+    }
+
+    handleTagInputFocus(){
+        this.ref.current.focus();
+    }
+
+    render() {
+        return (
+            <>
+                <TagInput defaultValue={['Tiktok','Hotsoon']} ref={this.ref} />
+                <Button style={{marginTop:10}} onClick={this.handleTagInputFocus}>
+                    focus
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### Custom TagInput rendering
+
+You can use `renderTagItem` to customize tag rendering.
+
+```jsx live=true
+import React from 'react';
+import { TagInput, Avatar } from '@douyinfe/semi-ui';
+
+class CustomRender extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            value : ['xiakeman']
+        }
+        this.list = [
+            { "name": "xiakeman", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"},
+            { "name": "shenyue",  "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg"},
+            { "name": "quchenyi", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg"},
+            { "name": "wenjiamao", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/7abf810ff060ac3387bd027ead92c4e0.jpg"},
+        ]
+        this.mapList = new Map(this.list.map( item => [item.name,item]));
+    }
+
+    renderTagItem(value,index) {
+        const data = this.mapList.get(value);
+        return (
+            <div 
+                key={index} 
+                style={{display: 'flex', alignItems: 'center', fontSize: 14, marginRight: 10}}
+            >
+                <Avatar 
+                    src={data?data.avatar:'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg'} 
+                    size="extra-small" 
+                />
+                <span style={{ marginLeft: 8 }}>
+                    {`${value}@semi.com`}
+                </span>
+            </div>
+        )
+    }
+
+    render() {
+        const { value } = this.state;
+        return (
+            <TagInput 
+                value={value} 
+                onChange={value=>this.setState({value})}
+                renderTagItem={(value,index)=>this.renderTagItem(value,index)}
+            />
+        );
+    }
+}
+``` 
+
+
+## API Reference
+
+|Properties    |Instructions                                     |Type                                                            |Default  |Version |
+|--------------|-------------------------------------------------|----------------------------------------------------------------|----------|--------|
+|addOnBlur     |Whether to automatically create the current input value into a tag when the blur event is triggered |boolean       | false    |1.20.0|
+|allowDuplicates|Allows adding the same tag multiple times       |boolean                                                          | true    |1.20.0|
+|autoFocus     |Set whether to automatically focus during initial rendering |boolean                                                          | false    |1.29.0|
+|className     |Class name                                       |string                                                           | -        |1.19.0|
+|defaultValue  |Default tag value                                |string[]                                                         | -         |1.19.0|
+|disabled      |Read-only, disable interaction                   |boolean                                                          |false     |1.19.0|
+|inputValue    |Controlled input value                          |string                                                          | -         |1.19.0|
+|maxLength     |Maximum length of a tag                          |number                                                           | -        |1.19.0|
+|max           |Maximum number of tags allowed                   |number                                                           | -        |1.21.0|
+|maxTagCount   |The maximum number of tags to be displayed, if exceeded, they will be displayed in the form of +N |number        | -        |1.21.0|
+|showRestTagsPopover |When maxTagCount is exceeded and hover reaches +N, whether to display the remaining content through Popover  |boolean     | true     |1.21.0|
+|restTagsPopoverProps |The configuration properties of the popover     |PopoverProps     | {}        |1.21.0|
+|showContentTooltip |When the tag is too long and truncated, when hovering the tag, whether to display all contents through Tooltip     |boolean    | true        |1.21.0|
+|placeholder   |Content to be appear by default                  |string                                                           | -         |1.19.0|
+|prefix        |Prefix                                           |ReactNode                                                        |-          |1.19.0|
+|renderTagItem |Customize the rendering of items                 |(value: string, index: number) => React.ReactNode                | -        |1.19.0|
+|separator     |Customize the separator                          |string\|string[]                                                 |,          |1.19.0,string[] is supported since 1.29.0|
+|showClear     |Whether to show the clear button                 |boolean                                                          |false      |1.19.0|
+|size          |Size, one of `small`、`large`、`default`          |string                                                           |`default` |1.19.0|
+|style         |Inline style                                     |React.CSSProperties                                               | -        |1.19.0|
+|suffix        |Suffix                                            |ReactNode                                                        |-         |1.19.0|
+|validateStatus|Validate status for styling only, one of  `default`、`warning`、`error`|string                                       |`default` |1.19.0|
+|value         |Controlled tag value                              |string[]                                                         | -        |1.19.0|
+|onAdd         |Callback invoked when tags are added             |(addedValue: string[]) => void                                   | -        |1.19.0|
+|onBlur        |Callback invoked when input loses focus          |(e:React.MouseEvent<HTMLInputElement\>) => void                  | -        |1.19.0|
+|onChange      |Callback invoked when tags changes               |(value:string[]) => void                                         | -        |1.19.0|
+|onExceed      |Callback invoked when max is exceeded    |(value:string[]) => void                                         | -        |1.19.0|
+|onFocus       |Callback invoked when input gets focus           |(e:React.MouseEvent<HTMLInputElement\>) => void                  | -        |1.19.0|
+|onInputChange |Callback invoked when input changes              |(value:string,e: React.KeyboardEvent<HTMLInputElement\>) => void)| -        |1.19.0|
+|onInputExceed |Callback invoked when maxLength is exceeded      |(value:string) => void                                           | -        |1.19.0|
+|onRemove      |Callback invoked when tags are removed           |(removedValue: string, idx: number) => void                                 | -        |1.19.0|
+
+## Methods
+
+|Name   |Description |Version |
+|-------|------------|--------|
+|blur() |Remove focus|1.19.0|
+|focus()|Get focus   |1.19.0|
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+
+```material
+192,176
+``` -->

+ 460 - 0
content/input/taginput/index.md

@@ -0,0 +1,460 @@
+---
+localeCode: zh-CN
+order: 28
+category: 输入类
+title: TagInput 标签输入框
+icon: doc-tagInput
+brief: 标签输入框能够将输入的内容生成标签。
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { TagInput } from '@douyinfe/semi-ui';
+```
+### 基本演示
+
+敲击回车键后,输入内容将成为标签。标签内容如果为空串或者纯空格时,则会被过滤。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        defaultValue={['抖音','火山','西瓜视频']}
+        placeholder='请输入...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### 批量添加
+
+可以使用 `separator` 设置分隔符,来实现批量输入,它的默认值为英文逗号。1.29.0 版本后支持多个分隔符以 string[] 格式传入。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput 
+            separator='-' 
+            placeholder='使用 - 进行批量输入'
+            onChange={v => console.log(v)}
+        />
+        <br/><br/>
+        <TagInput 
+            separator={['-', '/', '|', '++']}
+            placeholder='支持多个分隔符进行批量输入'
+            onChange={v => console.log(v)}
+        />
+    </>
+)
+```
+
+### 批量删除
+
+可使用 `showClear` 设置是否支持一键删除所有标签和输入框内容。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        showClear 
+        defaultValue={['抖音','火山']} 
+        placeholder='请输入...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### 禁用
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        disabled 
+        showClear 
+        defaultValue={['抖音','火山','西瓜视频']} 
+        placeholder='请输入...'
+    />
+)
+```
+
+### 尺寸大小
+
+通过 `size` 控制标签输入框的大小尺寸,可选: `small` 、 `default` 、 `large`。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput size='small' placeholder='small'/>
+        <br/><br/>
+        <TagInput placeholder='default'/>
+        <br/><br/>
+        <TagInput size='large' placeholder='large'/>
+    </>
+)
+```
+
+### 不同校验状态样式
+
+可以使用 `validateStatus` 设置不同校验状态的样式,它仅影响背景颜色等样式表现,可选值: `default` 、 `warning` 、 `error`。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput placeholder='default'/>
+        <br/><br/>
+        <TagInput placeholder='warning' validateStatus='warning'/>
+        <br/><br/>
+        <TagInput placeholder='error' validateStatus='error'/>
+    </>
+)
+``` 
+
+### 前缀 / 后缀
+
+可以通过 `prefix` 传入输入框前缀,通过 `suffix` 传入输入框后缀,可以为文本或者 ReactNode。  
+当 `prefix`、`suffix` 传入的内容为 string 或者 Icon 时,会自动带上左右间隔;若为自定义 ReactNode,则左右间隔为 0,如需可以在你传入的reactNode中自行设置。  
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
+
+() => (
+    <>
+        <TagInput prefix={<IconVigoLogo />} />
+        <br/><br/>
+        <TagInput prefix="Prefix" />
+        <br/><br/>
+        <TagInput suffix={<IconGift />} />
+        <br/><br/>
+        <TagInput suffix="Suffix" />
+    </>
+)
+``` 
+
+### 失焦后自动创建标签
+
+可使用 `addOnBlur`,设置是否在 blur 事件触发时,将当前 input 的值自动创建成 tag。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        defaultValue={['抖音','火山','西瓜视频']}
+        addOnBlur={true}
+        placeholder='请输入...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### 过滤重复标签
+
+可使用 `allowDuplicates`,设置是否允许创建相同 tag,默认为 true。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput
+        defaultValue={['抖音','火山','西瓜视频']}
+        allowDuplicates={false}
+        placeholder='请输入...'
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### 输入限制
+
+可使用 `max` 限制输入的标签数量,超出后将不允许再输入,并且触发 `onExceed()` 回调。
+
+可使用 `maxLength` 限制单个标签的最大长度,超出后将不允许再输入,并且触发 `onInputExceed()` 回调。
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <>
+        <TagInput 
+            max={3} 
+            placeholder='最多输入3条标签..' 
+            onChange={v => console.log(v)}
+            onExceed={v => {
+                Toast.warning('超过 max');
+                console.log(v);
+            }}
+        />
+        <TagInput 
+            maxLength={5} 
+            placeholder='单个标签长度不超过5...'  
+            style={{marginTop:12}}
+            onChange={v => console.log(v)}
+            onInputExceed={v => {
+                Toast.warning('超过 maxLength');
+                console.log(v);
+            }} 
+        />
+    </>
+)
+```
+
+### 限制标签展示数量
+
+利用 `maxTagCount` 可以限制展示的标签数量,超出部分将以 +N 的方式展示。使用 `showRestTagsPopover` 可以设置在超出 `maxTagCount` 后,hover +N 是否显示 `Popover`,并且可以在 `restTagsPopoverProps` 属性中配置 `Popover`。 
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        maxTagCount={2}
+        showRestTagsPopover={true}
+        restTagsPopoverProps={{ position: 'top' }}
+        defaultValue={['抖音','火山','西瓜视频']}
+        onChange={v => console.log(v)}
+    />
+)
+```
+
+### 标签受控
+
+可使用 `value` 设置标签内容,并配合 `onChange` 实现标签内容受控。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            value: ['抖音']
+        };
+    }
+    onChange(value) {
+        this.setState({ value });
+    }
+    
+    render() {
+        return (
+            <TagInput
+                value={this.state.value}
+                onChange={value => {this.onChange(value);}}
+            />
+        )
+    }
+}
+```
+
+### 输入受控
+
+可使用 `inputValue` 设置输入框内容,并配合 `onInputChange` 实现输入内容受控。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value: 'tiktok'
+        }
+    }
+    handleInputChange(value, event) {
+      this.setState({ value });
+    }
+    render() {
+        return (
+            <TagInput
+                inputValue={this.state.value}
+                onInputChange={(v,e) => this.handleInputChange(v,e)}
+            />
+        )
+    }
+}
+```
+
+### 回调
+
+```jsx live=true
+import React from 'react';
+import { TagInput } from '@douyinfe/semi-ui';
+
+() => (
+    <TagInput 
+        defaultValue={['抖音']} 
+        placeholder='请输入...'
+        showClear 
+        onFocus={e => {console.log(`onFocus`);}} 
+        onBlur={e => {console.log(`onBlur`);}} 
+        onChange={tag => {console.log(`onChange,当前标签数组:${tag}`);}} 
+        onAdd={tag => {console.log(`onAdd,新增:${tag}`);}} 
+        onRemove={(v,i) => {console.log(`onRemove,移除:${v}, 序号:${i}`);}} 
+        onInputChange={(input,e) => {console.log(`onInputChange,当前输入内容:${input}`);}} 
+    />
+)
+```
+
+### 焦点管理
+
+可以使用 `blur()` 和 `focus()` 方法对焦点进行管理。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { TagInput, Button } from '@douyinfe/semi-ui';
+
+class TagInputDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.ref = React.createRef();
+        this.handleTagInputFocus=this.handleTagInputFocus.bind(this);
+    }
+
+    handleTagInputFocus(){
+        this.ref.current.focus();
+    }
+
+    render() {
+        return (
+            <>
+                <TagInput defaultValue={['抖音','火山']} ref={this.ref} />
+                <Button style={{marginTop:10}} onClick={this.handleTagInputFocus}>
+                    点击按钮聚焦
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### 自定义标签渲染
+
+可以使用 `renderTagItem` 自定义标签渲染。
+
+```jsx live=true
+import React from 'react';
+import { TagInput, Avatar } from '@douyinfe/semi-ui';
+
+class CustomRender extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            value : ['夏可漫']
+        }
+        this.list = [
+            { "name": "夏可漫", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"},
+            { "name": "申悦",  "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg"},
+            { "name": "曲晨一", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg"},
+            { "name": "文嘉茂", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/7abf810ff060ac3387bd027ead92c4e0.jpg"},
+        ]
+        this.mapList = new Map(this.list.map( item => [item.name,item]));
+    }
+
+    renderTagItem(value,index) {
+        const data = this.mapList.get(value);
+        return (
+            <div 
+                key={index} 
+                style={{display: 'flex', alignItems: 'center', fontSize: 14, marginRight: 10}}
+            >
+                <Avatar 
+                    src={data?data.avatar:'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg'} 
+                    size="extra-small" 
+                />
+                <span style={{ marginLeft: 8 }}>
+                    {`${value}@semi.com`}
+                </span>
+            </div>
+        )
+    }
+
+    render() {
+        const { value } = this.state;
+        return (
+            <TagInput 
+                value={value} 
+                onChange={value=>this.setState({value})}
+                renderTagItem={(value,index)=>this.renderTagItem(value,index)}
+            />
+        );
+    }
+}
+``` 
+
+
+## API 参考
+
+|属性          |说明                                             |类型                            |默认值    |版本      |
+|-------------|-------------------------------------------------|-------------------------------|----------|--------|
+|addOnBlur    |是否在 blur 事件触发时,将当前 input 的值自动创建成 tag |boolean                        | false   |1.20.0|
+|allowDuplicates|是否允许添加相同 tag                             |boolean                         | true    |1.20.0|
+|autoFocus    |初始渲染时是否自动 focus                            |boolean                         | false    |1.29.0|
+|className    |样式类名                                          |string                         | -        |1.19.0|
+|defaultValue |初始标签                                          |string[]                        | -       |1.19.0|
+|disabled     |是否禁用                                          |boolean                        |false     |1.19.0|
+|inputValue   |当前输入框,配合 onInputChange 实现受控              |string                         | -        |1.19.0|
+|maxLength    |单个标签的最大长度                                  |number                         | -        |1.19.0|
+|max          |允许标签的最大数量                                  |number                         | -        |1.21.0|
+|maxTagCount  |标签的最大展示数量,超出后将以 +N 形式展示              |number                         | -        |1.21.0|
+|showRestTagsPopover  |当超过 maxTagCount,hover 到 +N 时,是否通过 Popover 显示剩余内容  |boolean     | true     |1.21.0|
+|restTagsPopoverProps |Popover 的配置属性,可以控制弹出方向、zIndex、trigger等,具体参考[Popover](/zh-CN/show/popover#API_参考)           |PopoverProps     | {}        |1.21.0|
+|showContentTooltip   |当标签长度过长发生截断时,hover 标签的时候,是否通过 Tooltip 显示全部内容     |boolean    | true        |1.21.0|
+|placeholder  |占位默认值                                         |string                         | -         |1.19.0|
+|prefix       |前缀标签                                           |ReactNode                      |-          |1.19.0|
+|renderTagItem|自定义标签渲染                                      |(value: string, index: number) => React.ReactNode | -        |1.19.0|
+|separator    |设置批量输入时的分隔符                               |string\|string[]                         |,    |1.19.0, string[]是从1.29.0开始支持|
+|showClear    |是否支持一键删除所有标签和输入内容                     |boolean                        |false      |1.19.0|
+|size         |设置输入框尺寸,可选: `small`、`large`、`default`     |string                          |`default` |1.19.0|
+|style        |内联样式                                          |React.CSSProperties                         | -        |1.19.0|
+|suffix       |后缀标签                                           |ReactNode                      |-         |1.19.0|
+|validateStatus|设置校验状态样式,可选: `default`、`warning`、`error` |string                          |`default` |1.19.0|
+|value        |当前标签,配合 onChange 实现受控                     |string[]                       | -        |1.19.0|
+|onAdd        |添加标签时的回调                                     |(addedValue: string[]) => void     | -        |1.19.0|
+|onBlur       |输入框失去焦点时的回调           |(e:React.MouseEvent<HTMLInputElement\>) => void                 | -        |1.19.0|
+|onChange     |标签变化时的回调                                     |(value:string[]) => void | -        |1.19.0|
+|onExceed     |超过 max 时的回调                           |(value:string[]) => void        | -        |1.19.0|
+|onFocus      |输入框获取焦点时的回调                                |(e:React.MouseEvent<HTMLInputElement\>) => void               | -        |1.19.0|
+|onInputChange|输入框内容变化时的回调                                |(value:string,e: React.KeyboardEvent<HTMLInputElement\>) => void)  | -        |1.19.0|
+|onInputExceed|超过 maxLength 时的回调                             |(value:string) => void          | -        |1.19.0|
+|onRemove     |移除标签时的回调                                     |(removedValue: string, idx: number) => void     | -        |1.19.0|
+## 方法
+
+|名称    |描述   |版本     |
+|-------|------|---------|
+|blur() |移出焦点|1.19.0|
+|focus()|获取焦点|1.19.0|
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+
+```material
+192,176
+``` -->

+ 331 - 0
content/input/timepicker/index-en-US.md

@@ -0,0 +1,331 @@
+---
+localeCode: en-US
+order: 29
+category: Input
+title: TimePicker
+subTitle: TimePicker
+icon: doc-timepicker
+brief: Users can easily select a compliant, formatted point of time using the time selector.
+---
+
+## When to Use
+
+When users need to enter a time, they can click on the standard input box and pop up the time panel to select.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { TimePicker } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+Click TimePicker, and then you can select or enter a time in the floating layer.
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <TimePicker />;
+}
+```
+
+### With an Embedded Label
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <TimePicker insetLabel="Time" />;
+}
+```
+
+### Controlled Component
+
+When using `value` And not. `defaultValue` When used as a controlled component.`value` and `onChange` It needs to be used in conjunction.
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            value: null,
+        };
+        this.onChange = this.onChange.bind(this);
+    }
+
+    onChange(time) {
+        console.log(time);
+        this.setState({ value: time });
+    }
+
+    render() {
+        return <TimePicker value={this.state.value} onChange={this.onChange} />;
+    }
+}
+```
+
+### Different Format
+
+The columns in the TimePicker float will follow `format` Change, when omitted `format` At some point, the corresponding column in the floating layer will also disappear.
+
+NOTE: `format` Follow the date-fns `format` Format. https://date-fns.org/v2.0.0/docs/format
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <TimePicker format={'HH:mm'} defaultValue={'10:24'} />;
+}
+```
+
+### Set Panel Header and Footer
+
+```jsx live=true
+import React, { useState } from 'react';
+import { TimePicker, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [open, setOpen] = useState(false);
+    const closePanel = () => setOpen(false);
+    const onOpenChange = open => {
+        setOpen(open);
+        console.log(open);
+    };
+
+    return (
+        <TimePicker
+            open={open}
+            onOpenChange={onOpenChange}
+            panelHeader={'Time Select'}
+            panelFooter={<Button onClick={closePanel}>close</Button>}
+        />
+    );
+}
+```
+
+### Disable Time Selection
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <TimePicker defaultValue={'12:08:23'} disabled />;
+}
+```
+
+### Set Step Length
+
+Available `Hour Step`, `Minute Step`, `Second Step` Show the optional minutes and seconds by step.
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return <TimePicker minuteStep={15} secondStep={10} />;
+}
+```
+
+### 12-hour System
+
+12-hour time selector, default `format` for `h:mm:ss a`, an incoming `format` The format must be in [dateFns date format](https://date-fns.org/v2.0.0/docs/format)Within range.
+
+> For example, the default 12-hour format string is:`a h:mm:ss`, if passed in `A h:mm:ss` This will result in an inability to format correctly.
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return (
+        <div>
+            <TimePicker use12Hours />
+            <br />
+            <br />
+            <TimePicker use12Hours format="a h:mm" />
+        </div>
+    );
+}
+```
+
+### Time Range
+
+**Version:** > = 0.23.0
+
+Pass type = "timeRange" to enable time range selection.
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+    return (
+        <div>
+            <TimePicker type="timeRange" defaultValue={['10:23:15', '12:38:32']} />
+            <br />
+            <br />
+            <TimePicker type="timeRange" use12Hours format="a h:mm" defaultValue={['AM 08:11', 'PM 11:21']} />
+        </div>
+    );
+}
+```
+
+### Custom Trigger
+
+**Version:** >=0.34.0
+
+By default we use the `Input` component as the trigger for the `DatePicker` component. You can customize this trigger by passing the `triggerRender` method.
+
+```jsx live=true hideInDSM
+import React, { useState, useMemo } from 'react';
+import * as dateFns from 'date-fns';
+import { TimePicker, Button } from '@douyinfe/semi-ui';
+import { IconChevronDown, IconClose } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const formatToken = 'HH:mm:ss';
+    const [time, setTime] = useState(new Date());
+    const triggerIcon = useMemo(() => {
+        return time ? (
+            <IconClose
+                onClick={e => {
+                    e && e.stopPropagation();
+                    setTime();
+                }}
+            />
+        ) : (
+            <IconChevronDown />
+        );
+    }, [time]);
+
+    return (
+        <TimePicker
+            value={time}
+            format={formatToken}
+            onChange={time => setTime(time)}
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={triggerIcon} iconPosition={'right'}>
+                    {time ? dateFns.format(time, formatToken) : placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+## TimeZone Config
+
+Semi All configuration about time zone is converged in [ConfigProvider](/en-US/other/configprovider)
+
+```jsx live=true hideInDSM
+import React, { useMemo, useState } from 'react';
+import { ConfigProvider, Select, TimePicker } from '@douyinfe/semi-ui';
+
+function Demo(props = {}) {
+    const [timeZone, setTimeZone] = useState('GMT+08:00');
+    const defaultTimestamp = 1581599305265;
+    const gmtList = useMemo(() => {
+        const list = [];
+        for (let hourOffset = -11; hourOffset <= 14; hourOffset++) {
+            const prefix = hourOffset >= 0 ? '+' : '-';
+            const hOffset = Math.abs(parseInt(hourOffset, 10));
+            list.push(`GMT${prefix}${String(hOffset).padStart(2, '0')}:00`);
+        }
+        return list;
+    }, []);
+
+    return (
+        <ConfigProvider timeZone={timeZone}>
+            <div style={{ width: 300 }}>
+                <h5 style={{ margin: 10 }}>Select Time Zone:</h5>
+                <Select
+                    placeholder={'Please Choose TimeZone'}
+                    style={{ width: 300 }}
+                    value={timeZone}
+                    showClear={true}
+                    onSelect={value => setTimeZone(value)}
+                >
+                    {gmtList.map(gmt => (
+                        <Select.Option key={gmt} value={gmt}>
+                            {gmt}
+                        </Select.Option>
+                    ))}
+                </Select>
+                <br />
+                <br />
+                <h5 style={{ margin: 10 }}>TimePicker:</h5>
+                <TimePicker
+                    defaultValue={defaultTimestamp}
+                    onChange={(date, dateString) => console.log('DatePicker changed: ', date, dateString)}
+                />
+            </div>
+        </ConfigProvider>
+    );
+}
+```
+
+## API Reference
+
+| Parameters | Instructions | Type | Default | Version |
+| --- | --- | --- | --- | --- |
+| autoAdjustOverflow | Whether the floating layer automatically adjusts its direction when it is blocked | boolean | true | **0.34.0** |
+| autoFocus | Automatic access to focus | boolean | false |
+| className | Outer style name | string |  |
+| clearText | Clear button prompt copy | string | Clear |
+| defaultOpen | Whether the panel is open by default | boolean |  | **0.19.0** |
+| defaultValue | Default time | Date\|timeStamp\|string (array when type = "timeRange") |  |
+| disabled | Disable all operations | boolean | false |
+| disabledHours | Prohibited selection of partial hour options | () => number [] |  |
+| disabledMinutes | Prohibited to select some minute options | (selectedHour: number) => number[] |  |
+| disabledSeconds | Unable to select partial second option | (selectedHour: number, selectedMinute: number) => number[] |  |
+| focusOnOpen     | Whether to open the panel and focus the input box when mounting                         | boolean                                                                            | false                                                     |                    |
+| format | Time format of presentation | string | "HH: mm: ss." |  |
+| getPopupContainer | Specifies the container and the floating layer will be rendered into the element, you need to set 'position: relative` | () => HTMLElement | () => document.body |
+| hideDisabledOptions | Hide the option of forbidden selection | boolean | false |
+| hourStep | Hour option interval | number | 1 |
+| inputReadOnly | Set the input box to read-only (avoid opening a virtual keyboard on a mobile device) | boolean | false |
+| insetLabel | Prefix label, lower priority than `prefix` | string\|ReactNode |  |  |
+| minuteStep | Minute option interval | number | 1 |
+| motion | Whether to display the pop-up layer animation | boolean | true |  |
+| open | Controlled property of whether the panel is open | boolean |  |
+| panelFooter | Addon at the bottom of the panel | ReactNode\|string |  |
+| panelHeader | Panel head addon | ReactNode\|string |  |
+| placeholder | What's displayed when it's not worth it. | string | "Select time" |
+| popupClassName | Pop-up class name | string | '' |
+| popupStyle | Pop-up layer style object | object | - |
+| position | Floating position | string | type="timeRange" => "bottom"<br/>type="time" => "bottomLeft" |
+| prefixCls | Prefix content | string\|ReactNode |  |  |
+| rangeSeparator | time range delimiter | string | "~" |
+| scrollItemProps | The props passed through to ScrollItem. The optional values are the same as [ScrollList#API](/zh-CN/show/scrolllist#ScrollItem) | object |  | **0.31.0** |
+| secondStep | Second option interval | number | 1 |
+| showClear | Do you show the clear button? **v>=0.35.0** | boolean | true |
+| size  | Size of input box, one of 'default', 'small' and 'large'          | string                                                                   | 'default'                                                              |                    |
+| triggerRender | Custom trigger rendering method | ({ placeholder: string }) => ReactNode |  | **0.34.0** |
+| type | type | "time"\|"timeRange" | "time" |
+| use12Hours | Using a 12-hour system, `format` default to `h: mm: ssa` when true | boolean | false |
+| value | Current time | Date\|timeStamp\|string (array when type = "timeRange") |  |
+| onBlur | Callback when focus is lost | (e: domEvent) => void | () => {} | **1.0.0** |
+| onChange | A callback in time. | (time: Date\|Date[], timeString: string\|string[]) => void |  |
+| onFocus | Callback when focus is obtained | (e: domEvent) => void | () => {} | **1.0.0** |
+| onOpenChange | A callback when the panel is on / off | (isOpen: boolean) => void |  |
+
+## Method
+
+| Name    | Description   |
+| ------- | ------------- |
+| blur()  | Remove focus  |
+| focus() | Get the focus |
+
+## Design Tokens
+
+<DesignToken/>

+ 315 - 0
content/input/timepicker/index.md

@@ -0,0 +1,315 @@
+---
+localeCode: zh-CN
+order: 29
+category: 输入类
+title: TimePicker 时间选择器
+icon: doc-timepicker
+breif: 用户使用时间选择器可以方便地选择某一符合要求的、格式化的时间点
+---
+
+
+## 何时使用
+
+当用户需要输入一个时间,可以点击标准输入框,弹出时间面板进行选择。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { TimePicker } from '@douyinfe/semi-ui';
+```
+### 基础使用
+
+点击 TimePicker,然后可以在浮层中选择或者输入某一时间。
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return <TimePicker />;
+}
+```
+
+### 带内嵌标签
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return <TimePicker insetLabel='时刻'/>;
+}
+```
+
+### 受控组件
+
+当使用 `value` 而不是 `defaultValue` 时,作为受控组件使用。`value` 和 `onChange` 需要配合使用。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+  constructor() {
+    super();
+    this.state = {
+      value: null,
+    };
+    this.onChange = this.onChange.bind(this);
+  }
+
+  onChange(time) {
+    console.log(time);
+    this.setState({ value: time });
+  };
+
+  render() {
+    return <TimePicker value={this.state.value} onChange={this.onChange} />;
+  }
+}
+```
+
+### 不同的 Format 格式
+
+TimePicker 浮层中的列会随着 `format` 变化,当略去 `format` 中的某部分时,浮层中对应的列也会消失。
+
+NOTE: `format` 遵循 date-fns 的 `format` 格式。 https://date-fns.org/v2.0.0/docs/format
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return <TimePicker format={'HH:mm'} defaultValue={'10:24'}/>;
+}
+```
+
+### 设置面板头部,底部
+
+```jsx live=true
+import React, { useState } from 'react';
+import { TimePicker, Button } from '@douyinfe/semi-ui';
+
+function Demo() {
+  const [open, setOpen] = useState(false);
+  const closePanel = () => setOpen(false);
+  const onOpenChange = (open) =>  {
+    setOpen(open);
+    console.log(open);
+  };
+
+  return <TimePicker open={open} onOpenChange={onOpenChange} panelHeader={'Time Select'} panelFooter={<Button onClick={closePanel}>close</Button>}/>;
+}
+```
+
+### 禁用时间选择
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return <TimePicker defaultValue={'12:08:23'} disabled />;
+}
+```
+
+### 设置步长
+
+可以使用 `hourStep`, `minuteStep`, `secondStep` 按步长展示可选的时分秒。
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return <TimePicker minuteStep={15} secondStep={10} />;
+}
+```
+
+### 12 小时制
+
+12 小时制的时间选择器,默认的 `format` 为 `h:mm:ss a`,传入的 `format` 格式必须在 [dateFns 日期格式](https://date-fns.org/v2.0.0/docs/format)范围之内。
+
+> 例如默认的 12 小时制格式串为:`a h:mm:ss`,如果传入 `A h:mm:ss` 则会导致无法正确格式化。
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return (
+    <div>
+      <TimePicker use12Hours /><br/><br/>
+      <TimePicker use12Hours format="a h:mm" />
+    </div>
+  );
+}
+```
+
+### 时间范围
+
+**版本:** >=0.23.0
+
+传入 type="timeRange" 开启时间范围选择。
+
+```jsx live=true
+import React from 'react';
+import { TimePicker } from '@douyinfe/semi-ui';
+
+function Demo() {
+  return (
+    <div>
+      <TimePicker type="timeRange" defaultValue={["10:23:15", "12:38:32"]} /><br/><br/>
+      <TimePicker type="timeRange" use12Hours format="a h:mm" defaultValue={["上午 08:11", "下午 11:21"]} />
+    </div>
+  );
+}
+```
+
+### 自定义触发器
+
+**版本:**>=0.34.0
+
+默认情况下我们使用 `Input` 组件作为 `TimePicker` 组件的触发器,通过传递 `triggerRender` 方法你可以自定义这个触发器。
+
+```jsx live=true hideInDSM
+import React, { useState, useMemo } from 'react';
+import * as dateFns from 'date-fns';
+import { TimePicker, Button } from '@douyinfe/semi-ui';
+import { IconChevronDown, IconClose } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const formatToken = 'HH:mm:ss';
+    const [time, setTime] = useState(new Date());
+    const triggerIcon = useMemo(() => {
+        return time ? (
+            <IconClose
+                onClick={e => {
+                    e && e.stopPropagation();
+                    setTime();
+                }}
+            />
+        ) : (
+            <IconChevronDown />
+        );
+    }, [time]);
+
+    return (
+        <TimePicker
+            value={time}
+            format={formatToken}
+            onChange={time => setTime(time)}
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={triggerIcon} iconPosition={'right'}>
+                    {time ? dateFns.format(time, formatToken) : placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+## 时区设置
+
+Semi 所有关于时区的配置都收敛在 ConfigProvider 中,详细使用可以参考 [ConfigProvider](/zh-CN/other/configprovider)
+
+```jsx live=true hideInDSM
+import React, { useMemo, useState } from 'react';
+import { ConfigProvider, Select, TimePicker } from '@douyinfe/semi-ui';
+
+function Demo(props = {}) {
+    const [timeZone, setTimeZone] = useState('GMT+08:00');
+    const defaultTimestamp = 1581599305265;
+    const gmtList = useMemo(() => {
+        const list = [];
+        for(let hourOffset = -11; hourOffset <= 14 ; hourOffset++) {
+            const prefix = hourOffset >= 0 ? '+' : '-';
+            const hOffset = Math.abs(parseInt(hourOffset, 10));
+            list.push(`GMT${prefix}${String(hOffset).padStart(2, '0')}:00`)
+        }
+        return list;
+    }, []);
+
+    return (
+        <ConfigProvider timeZone={timeZone}>
+            <div style={{ width: 300 }}>
+                <h5 style={{ margin: 10 }}>Select Time Zone:</h5>
+                <Select
+                    placeholder={'请选择时区'}
+                    style={{ width: 300 }}
+                    value={timeZone}
+                    showClear={true}
+                    onSelect={value => setTimeZone(value)}
+                >
+                    {gmtList.map(gmt => (
+                        <Select.Option key={gmt} value={gmt}>
+                            {gmt}
+                        </Select.Option>
+                    ))}
+                </Select>
+                <br/> 
+                <br/> 
+                <h5 style={{ margin: 10 }}>TimePicker:</h5>
+                <TimePicker defaultValue={defaultTimestamp} onChange={(date, dateString) => console.log('DatePicker changed: ', date, dateString)} />
+            </div>
+        </ConfigProvider>
+    );
+}
+```
+
+## API 参考
+
+| 参数                | 说明                                                   | 类型                                                                              | 默认值                                                            | 版本               |
+| ------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------ |
+| autoAdjustOverflow  | 浮层被遮挡时是否自动调整方向                           | boolean                                                                           | true                                                              | **0.34.0** |
+| autoFocus           | 自动获取焦点                                           | boolean                                                                           | false                                                             |                    |
+| className           | 外层样式名                                             | string                                                                            |                                                                   |                    |
+| clearText           | 清除按钮的提示文案                                     | string                                                                            | clear                                                             |                    |
+| defaultOpen         | 面板是否默认打开                                       | boolean                                                                           |                                                                   | **0.19.0**         |
+| defaultValue        | 默认时间                                               | Date\|timeStamp\|String(type="timeRange"时为数组)                               |                                                                   |                    |
+| disabled            | 禁用全部操作                                           | boolean                                                                           | false                                                             |                    |
+| disabledHours       | 禁止选择部分小时选项                                   | Function(): number[]                                                              |                                                                   |                    |
+| disabledMinutes     | 禁止选择部分分钟选项                                   | Function(selectedHour: number): number[]                                          |                                                                   |                    |
+| disabledSeconds     | 禁止选择部分秒选项                                     | Function(selectedHour: number, selectedMinute: number): number[]                  |                                                                   |                    |
+| focusOnOpen         | 挂载时是否打开面板并focus输入框                         | boolean                                                                            | false                                                     |                    |
+| format              | 展示的时间格式                                         | string                                                                            | "HH:mm:ss"                                                        |                    |
+| getPopupContainer   | 指定容器,浮层将会渲染至该元素内,自定义需要设置 `position: relative`                       | Function(): HTMLElement                                                           | () => document.body                                               |                    |
+| hideDisabledOptions | 隐藏禁止选择的选项                                     | boolean                                                                           | false                                                             |                    |
+| hourStep            | 小时选项间隔                                           | number                                                                            | 1                                                                 |                    |
+| inputReadOnly       | 设置输入框为只读(避免在移动设备上打开虚拟键盘)       | boolean                                                                           | false                                                             |                    |
+| insetLabel          | 前缀标签,优先级低于 `prefix`                          | string\|ReactNode                                                                 |                                                                   |                    |
+| minuteStep          | 分钟选项间隔                                           | number                                                                            | 1                                                                 |                    |
+| motion | 是否展示弹出层动画 | boolean | true |  |
+| open                | 面板是否打开的受控属性                                 | boolean                                                                           |                                                                   |                    |
+| panelFooter         | 面板底部 addon                                         | ReactNode\|string                                                                 | 无                                                                |                    |
+| panelHeader         | 面板头部 addon                                         | ReactNode\|string                                                                 | 无                                                                |                    |
+| placeholder         | 没有值的时候显示的内容                                 | string                                                                            | "请选择时间"                                                      |                    |
+| popupClassName      | 弹出层类名                                             | string                                                                            | ''                                                                |                    |
+| popupStyle          | 弹出层样式对象                                         | object                                                                            | -                                                                 |                    |
+| position            | 浮层位置                                               | string                                                                            | type="timeRange"时默认为"bottom",type="time"时默认为"bottomLeft" |                    |
+| prefixCls              | 前缀内容                                               | string\|ReactNode                                                                 |                                                                   |                    |
+| rangeSeparator      | 时间范围分隔符                                         | string                                                                            | " ~ "                                                             |                    |
+| scrollItemProps     | 透传给 scrollItem 的属性,可选值同[ScrollList#API](/zh-CN/show/scrolllist#ScrollItem)                                                | object                                                           | | **0.31.0**         |
+| secondStep          | 秒选项间隔                                             | number                                                                            | 1                                                                 |                    |
+| showClear           | 是否展示清除按钮 **v>=0.35.0**                         | boolean                                                                           | true                                                              |                    |
+| size                | 输入框的大小,可选 'default','small','large'          | string                                                                   | 'default'                                                              |                    |
+| triggerRender       | 自定义触发器渲染方法                                   | ({ placeholder: string }) => ReactNode                                            | -                                                                 | **0.34.0**  |
+| type                | 类型                                                   | "time"\|"timeRange"                                                               | "time"                                                            |                    |
+| use12Hours          | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean                                                                           | false                                                             |                    |
+| value               | 当前时间                                               | Date\|timeStamp\|String(type="timeRange"时为数组)                               |                                                                   |                    |
+| onBlur              | 失去焦点时的回调                                       | (e: domEvent) => void                                                             | () => {}                                                          | **1.0.0**          |
+| onChange            | 时间发生变化的回调                                     | Function(time: Date, timeString: string): void (type="timeRange"时入参皆为数组) | 无                                                                |                    |
+| onFocus             | 获得焦点时的回调                                       | (e: domEvent) => void                                                             | () => {}                                                          | **1.0.0**          |
+| onOpenChange        | 面板打开/关闭时的回调                                  | Function(isOpen: boolean): void                                                   | 无                                                                |                    |
+
+## 方法
+
+| 名称    | 描述     |
+| ------- | -------- |
+| blur()  | 移除焦点 |
+| focus() | 获取焦点 |
+
+## 设计变量
+<DesignToken/>

+ 946 - 0
content/input/transfer/index-en-US.md

@@ -0,0 +1,946 @@
+---
+localeCode: en-US
+order: 30
+category: Input
+title: Transfer
+icon: doc-transfer
+width: 60%
+dir: column
+brief: A more intuitive and efficient multiple-selection selector, which can reveal more information about options, and supports search functions. The disadvantage is that it takes up more space
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Transfer } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+dataSource should have value、label、key.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const data = Array.from({ length: 100 }, (v, i) => {
+        return {
+            label: `Item ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            dataSource={data}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### Grouped
+
+Set type to `groupList`
+
+For grouped dataSource, the first-level child elements must have title and children attributes, structure reference <GroupItem\>
+
+Does not support multi-level nesting
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const dataWithGroup = [
+        {
+            title: 'GroupA',
+            children: [
+                { label: 'A-1', value: 1, disabled: false, key: 1 },
+                { label: 'A-2', value: 2, disabled: false, key: 2 },
+                { label: 'A-3', value: 3, disabled: false, key: 3 },
+            ],
+        },
+        {
+            title: 'GroupB',
+            children: [
+                { label: 'B-1', value: 4, disabled: false, key: 4 },
+                { label: 'B-2', value: 5, disabled: false, key: 5 },
+                { label: 'B-3(disabled)', value: 6, disabled: true, key: 6 },
+            ],
+        },
+        {
+            title: 'GroupC',
+            children: [
+                { label: 'C-1', value: 7, disabled: false, key: 7 },
+                { label: 'C-2', value: 8, disabled: false, key: 8 },
+                { label: 'C-3', value: 9, disabled: false, key: 9 },
+                { label: 'C-4', value: 10, disabled: false, key: 10 },
+                { label: 'C-5', value: 11, disabled: false, key: 11 },
+                { label: 'C-6', value: 12, disabled: false, key: 12 },
+                { label: 'C-7', value: 13, disabled: false, key: 13 },
+            ],
+        },
+    ];
+    return (
+        <Transfer
+            type="groupList"
+            defaultValue={[6]}
+            style={{ width: 568 }}
+            dataSource={dataWithGroup}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### Custom filtering logic, custom option data rendering
+
+Use `filter` to customize the search logic. When it returns true, it means that the current item meets the filter rules and keeps the display of the current item in the list. If it returns false, it means it does not match, and the current item will be hidden.
+Using `renderSourceItem`, you can customize the rendering structure of each source data on the left
+Using `renderSelectedItem` you can customize the rendering structure of each selected item on the right
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Avatar, Checkbox } from '@douyinfe/semi-ui';
+import { IconClose } from '@douyinfe/semi-icons';
+
+() => {
+    const renderSourceItem = item => {
+        return (
+            <div className="components-transfer-demo-source-item" key={item.label}>
+                <Checkbox
+                    onChange={() => {
+                        item.onChange();
+                    }}
+                    key={item.label}
+                    checked={item.checked}
+                    style={{ height: 52 }}
+                >
+                    <Avatar color={item.color} size="small">
+                        {item.abbr}
+                    </Avatar>
+                    <div className="info">
+                        <div className="name">{item.label}</div>
+                        <div className="email">{item.value}</div>
+                    </div>
+                </Checkbox>
+            </div>
+        );
+    };
+
+    const renderSelectedItem = item => {
+        return (
+            <div className="components-transfer-demo-selected-item" key={item.label}>
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div className="info">
+                    <div className="name">{item.label}</div>
+                    <div className="email">{item.value}</div>
+                </div>
+                <IconClose onClick={item.onRemove} />
+            </div>
+        );
+    };
+
+    const customFilter = (sugInput, item) => {
+        return item.value.includes(sugInput) || item.label.includes(sugInput);
+    };
+
+    const data = [
+        { label: 'Xiakeman', value: '[email protected]', abbr: 'Xia', color: 'amber', area: 'tiktok-US', key: 1 },
+        { label: 'Shenyue', value: '[email protected]', abbr: 'Shen', color: 'indigo', area: 'tiktok-UK', key: 2 },
+        { label: 'Wenjiamao', value: '[email protected]', abbr: 'Wen', color: 'cyan', area: 'tiktok-HK', key: 3 },
+        { label: 'Quchenyi', value: '[email protected]', abbr: 'Qu', color: 'blue', area: 'vigo-India', key: 4 },
+        { label: 'Quchener', value: '[email protected]', abbr: 'Qu', color: 'blue', area: 'vigo-India', key: 5 },
+        { label: 'Quchensan', value: '[email protected]', abbr: 'Qu', color: 'blue', area: 'vigo-India', key: 6 },
+    ];
+
+    return (
+        <Transfer
+            style={{ width: 568 }}
+            dataSource={data}
+            filter={customFilter}
+            defaultValue={['[email protected]', '[email protected]']}
+            renderSelectedItem={renderSelectedItem}
+            renderSourceItem={renderSourceItem}
+            inputProps={{ placeholder: 'Search for a name or email' }}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+```css
+.components-transfer-demo-selected-item {
+    .semi-icon-close {
+        visibility: hidden;
+        color: var(--semi-color-tertiary);
+    }
+    &:hover {
+        .semi-icon-close {
+            visibility: visible;
+        }
+    }
+}
+
+.components-transfer-demo-selected-item,
+.components-transfer-demo-source-item {
+    height: 52px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 10px 12px;
+    &:hover {
+        background-color: var(--semi-color-fill-0);
+    }
+    .info {
+        margin-left: 8px;
+        flex-grow: 1;
+    }
+    .name {
+        font-size: 14px;
+        line-height: 20px;
+    }
+    .email {
+        font-size: 12px;
+        line-height: 16px;
+        color: var(--semi-color-text-2);
+    }
+}
+```
+
+### Disabled
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const data = Array.from({ length: 20 }, (v, i) => {
+        return {
+            label: `Item ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            disabled
+            dataSource={data}
+            defaultValue={[2, 4]}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### Drag and drop sort
+
+Set `draggable` to true to enable the drag sort function. Support after v1.11.0
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const data = Array.from({ length: 30 }, (v, i) => {
+        return {
+            label: `Item ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            dataSource={data}
+            defaultValue={[2, 4]}
+            draggable
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### Drag and drop + custom selected rendering
+
+Set `draggable` to true to enable the drag and drop sorting function; use `renderSelectedItem` to customize the rendering of the selected items on the right;
+You can define the trigger as any ReactNode you want and add styles. Drag the trigger and use `sortableHandle` to wrap it (sortableHandle is provided after v 1.22.0)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Checkbox, Avatar } from '@douyinfe/semi-ui';
+import { IconHandle, IconClose } from '@douyinfe/semi-icons';
+
+() => {
+    const renderSourceItem = item => {
+        return (
+            <div className="components-transfer-demo-source-item" key={item.label}>
+                <Checkbox
+                    onChange={() => {
+                        item.onChange();
+                    }}
+                    key={item.label}
+                    checked={item.checked}
+                    style={{ height: 52 }}
+                >
+                    <Avatar color={item.color} size="small">
+                        {item.abbr}
+                    </Avatar>
+                    <div className="info">
+                        <div className="name">{item.label}</div>
+                        <div className="email">{item.value}</div>
+                    </div>
+                </Checkbox>
+            </div>
+        );
+    };
+
+    const renderSelectedItem = item => {
+        const { sortableHandle } = item;
+        const DragHandle = sortableHandle(() => <IconHandle className={`semi-right-item-drag-handler`} />); 
+        return (
+            <div className="components-transfer-demo-selected-item" key={item.label}>
+                <DragHandle />
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div className="info">
+                    <div className="name">{item.label}</div>
+                    <div className="email">{item.value}</div>
+                </div>
+                <IconClose onClick={item.onRemove} />
+            </div>
+        );
+    };
+
+    const customFilter = (sugInput, item) => {
+        return item.value.includes(sugInput) || item.label.includes(sugInput);
+    };
+
+    const data = [
+        { label: 'Xiakeman', value: '[email protected]', abbr: 'Xia', color: 'amber', area: 'tiktok-US', key: 1 },
+        { label: 'Shenyue', value: '[email protected]', abbr: 'Shen', color: 'indigo', area: 'tiktok-UK', key: 2 },
+        { label: 'Wenjiamao', value: '[email protected]', abbr: 'Wen', color: 'cyan', area: 'tiktok-HK', key: 3 },
+        { label: 'Quchenyi', value: '[email protected]', abbr: 'Qu', color: 'blue', area: 'vigo-India', key: 4 },
+        { label: 'Quchener', value: '[email protected]', abbr: 'Er', color: 'blue', area: 'vigo-India', key: 5 },
+        { label: 'Quchensan', value: '[email protected]', abbr: 'San', color: 'blue', area: 'vigo-India', key: 6 },
+    ];
+
+    return (
+        <Transfer
+            draggable
+            style={{ width: 568 }}
+            dataSource={data}
+            filter={customFilter}
+            defaultValue={['[email protected]', '[email protected]']}
+            renderSelectedItem={renderSelectedItem}
+            renderSourceItem={renderSourceItem}
+            inputProps={{ placeholder: 'Search for a name or email' }}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### Fully custom rendering
+
+Semi provides `renderSourcePanel` and `renderSelectedPanel` input parameters, allowing you to completely customize the rendering structure of the left and right panels
+With this function, you can directly reuse the logic capabilities inside the Transfer to implement the `Transfer` component with a highly customized style structure `renderSourcePanel: (sourcePanelProps: SourcePanelProps) => ReactNode`
+`SourcePanelProps` contains the following parameters, from which you can get data to render your Panel structure
+
+```ts
+interface SourcePanelProps {
+   value: Array<string|number>; // key of all selected items
+   loading: boolean; // Whether loading
+   noMatch: boolean; // Whether there is no matching item that matches the current search value
+   filterData: Array<Item> // items that match the current search value
+   sourceData: Array<Item>; // All items
+   allChecked: boolean; // Whether to select all
+   showNumber: number; // Filter the number of results
+   inputValue: string; // the value of the input search box
+   onSearch: (searchString: string) => any; // The function that should be called when the search box changes, the input parameter is the search value
+   onAllClick: () => void; // The function that should be called when all the buttons on the left are clicked
+   onSelectOrRemove: (item: Item) => any; //The function that should be called when selecting or deleting a single option, the input should be the current operation item
+   onSelect: (value:Array<string|number>)=>void; // controlled batch selection key
+   selectedItem: Map, // collection of all selected items
+}
+```
+
+`renderSelectedPanel: (selectedPanelProps: SelectedPanelProps) => ReactNode`
+`SelectedPanelProps` contains the following parameters
+
+```ts
+interface SelectedPanelProps {
+   length: number; // number of selected options
+   onClear: () => void; // The callback function that should be called when clicking to clear
+   onRemove: (item: Item) => void; // The function that should be called when deleting a single option
+   onSortEnd: (( oldIndex, newIndex)) => void; // The function that should be called when reordering the results
+   selectedData: Array<Item>; // All selected items collection
+}
+```
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Input, Spin, Button } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class CustomRenderDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            dataSource: Array.from({ length: 100 }, (v, i) => ({
+                label: `Haidilao Store ${i}`,
+                value: i,
+                disabled: false,
+                key: i,
+            })),
+        };
+        this.renderSourcePanel = this.renderSourcePanel.bind(this);
+        this.renderSelectedPanel = this.renderSelectedPanel.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+    }
+
+    renderItem(type, item, onItemAction, selectedItems) {
+        let buttonText = 'delete';
+        if (type === 'source') {
+            let checked = selectedItems.has(item.key);
+            buttonText = checked ? 'delete' : 'add';
+        }
+        return (
+            <div className="semi-transfer-item panel-item" key={item.label}>
+                <p>{item.label}</p>
+                <Button
+                    theme="borderless"
+                    type="primary"
+                    onClick={() => onItemAction(item)}
+                    className="panel-item-remove"
+                    size="small"
+                >
+                    {buttonText}
+                </Button>
+            </div>
+        );
+    }
+
+    renderSourcePanel(props) {
+        const {
+            loading,
+            noMatch,
+            filterData,
+            selectedItems,
+            allChecked,
+            onAllClick,
+            inputValue,
+            onSearch,
+            onSelectOrRemove,
+        } = props;
+        let content;
+        switch (true) {
+            case loading:
+                content = <Spin loading />;
+                break;
+            case noMatch:
+                content = <div className="empty sp-font">{inputValue ? 'No search results' : 'No content yet'}</div>;
+                break;
+            case !noMatch:
+                content = filterData.map(item => this.renderItem('source', item, onSelectOrRemove, selectedItems));
+                break;
+            default:
+                content = null;
+                break;
+        }
+        return (
+            <section className="source-panel">
+                <div className="panel-header sp-font">Store list</div>
+                <div className="panel-main">
+                    <Input
+                        style={{ width: 454, margin: '12px 14px' }}
+                        prefix={<IconSearch />}
+                        onChange={onSearch}
+                        showClear
+                    />
+                    <div className="panel-controls sp-font">
+                        <span>Store to be selected: {filterData.length}</span>
+                        <Button onClick={onAllClick} theme="borderless" size="small">
+                            {allChecked ? 'Unselect all' : 'Select all'}
+                        </Button>
+                    </div>
+                    <div className="panel-list">{content}</div>
+                </div>
+            </section>
+        );
+    }
+
+    renderSelectedPanel(props) {
+        const { selectedData, onClear, clearText, onRemove } = props;
+
+        let mainContent = selectedData.map(item => this.renderItem('selected', item, onRemove));
+
+        if (!selectedData.length) {
+            mainContent = <div className="empty sp-font">No data, please filter from the left</div>;
+        }
+
+        return (
+            <section className="selected-panel">
+                <div className="panel-header sp-font">
+                    <div>Selected sync store: {selectedData.length}</div>
+                    <Button theme="borderless" type="primary" onClick={onClear} size="small">
+                        {clearText || 'Clear '}
+                    </Button>
+                </div>
+                <div className="panel-main">{mainContent}</div>
+            </section>
+        );
+    }
+
+    render() {
+        const { dataSource } = this.state;
+        return (
+            <Transfer
+                onChange={values => console.log(values)}
+                className="component-transfer-demo-custom-panel"
+                renderSourcePanel={this.renderSourcePanel}
+                renderSelectedPanel={this.renderSelectedPanel}
+                dataSource={dataSource}
+            />
+        );
+    }
+}
+```
+
+```scss
+.component-transfer-demo-custom-panel {
+    .sp-font {
+        color: rgba(var(--semi-grey-9), 1);
+        font-size: 12px;
+        font-weight: 500;
+        line-height: 20px;
+    }
+    .empty {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+    .panel-item {
+        width: 176px;
+        height: 56px;
+        border-radius: 4px;
+        margin-bottom: 8px;
+        padding: 8px 12px;
+        flex-wrap: wrap;
+        background-color: rgba(22, 24, 35, 0.03);
+        &-main {
+            flex-grow: 1;
+        }
+        p {
+            margin: 0 12px;
+            flex-basis: 100%;
+        }
+        .panel-item-remove {
+            cursor: pointer;
+            color: var(--semi-color-primary);
+        }
+    }
+    .source-panel {
+        width: 482px;
+        height: 353px;
+        border: 1px solid var(--semi-color-border);
+        border-top: none;
+        .panel-list {
+            overflow-y: auto;
+            height: 202px;
+            display: flex;
+            margin-left: 12px;
+            margin-right: 12px;
+            flex-wrap: wrap;
+        }
+        .panel-controls {
+            margin: 10px 12px;
+            font-size: 12px;
+            line-height: 20px;
+            .semi-button {
+                margin-left: 8px;
+                font-size: 12px;
+            }
+        }
+        .panel-item {
+            margin-right: 8px;
+        }
+        margin-right: 16px;
+    }
+    .selected-panel {
+        width: 200px;
+        height: 353px;
+        .panel-main {
+            overflow-y: auto;
+            padding: 12px;
+            border: 1px solid var(--semi-color-border);
+            border-top: none;
+            height: 315px;
+            box-sizing: border-box;
+        }
+    }
+    .panel-header {
+        padding: 10px 12px;
+        border: 1px solid rgba(22, 24, 35, 0.16);
+        border-radius: 4px 4px 0 0;
+        height: 38px;
+        box-sizing: border-box;
+        background-color: var(--semi-color-tertiary-light-default);
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .clear {
+            cursor: pointer;
+            color: var(--semi-color-primary);
+        }
+    }
+}
+```
+
+### Fully custom rendering, drag and drop sorting
+
+In a completely custom rendering scene, since the rendering of the drag area has also been completely taken over by you, you do not need to declare draggable.
+But you need to implement the drag and drop logic yourself, we recommend using `react-sortable-hoc` directly
+To support drag sorting, you need to call onSortEnd with oldIndex and newIndex as the input parameters after the drag sorting is over
+
+```jsx live=true dir="column"
+import React from 'react';
+import { SortableContainer, SortableElement, sortableHandle } from 'react-sortable-hoc';
+import { Transfer, Button, Spin, Input } from '@douyinfe/semi-ui';
+import { IconHandle, IconSearch } from '@douyinfe/semi-icons';
+
+class CustomRenderDragDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            dataSource: Array.from({ length: 100 }, (v, i) => ({
+                label: `Haidilao Store ${i}`,
+                value: i,
+                disabled: false,
+                key: i,
+            })),
+        };
+        this.renderSourcePanel = this.renderSourcePanel.bind(this);
+        this.renderSelectedPanel = this.renderSelectedPanel.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+    }
+
+    renderItem(type, item, onItemAction, selectedItems) {
+        let buttonText = 'delete';
+        let newItem = item;
+
+        if (type === 'source') {
+            let checked = selectedItems.has(item.key);
+            buttonText = checked ? 'delete' : 'add';
+        } else {
+            // delete newItem._optionKey;
+            newItem = { ...item, key: item._optionKey };
+            delete newItem._optionKey;
+        }
+
+        const DragHandle = sortableHandle(() => <IconHandle className="pane-item-drag-handler" />);
+
+        return (
+            <div className="semi-transfer-item panel-item" key={item.label}>
+                {type === 'source' ? null : <DragHandle />}
+                <div className="panel-item-main" style={{ flexGrow: 1 }}>
+                    <p>{item.label}</p>
+                    <Button
+                        theme="borderless"
+                        type="primary"
+                        onClick={() => onItemAction(newItem)}
+                        className="panel-item-remove"
+                        size="small"
+                    >
+                        {buttonText}
+                    </Button>
+                </div>
+            </div>
+        );
+    }
+
+    renderSourcePanel(props) {
+        const {
+            loading,
+            noMatch,
+            filterData,
+            selectedItems,
+            allChecked,
+            onAllClick,
+            inputValue,
+            onSearch,
+            onSelectOrRemove,
+        } = props;
+        let content;
+        switch (true) {
+            case loading:
+                content = <Spin loading />;
+                break;
+            case noMatch:
+                content = <div className="empty sp-font">{inputValue ? 'No search results' : 'No content yet'}</div>;
+                break;
+            case !noMatch:
+                content = filterData.map(item => this.renderItem('source', item, onSelectOrRemove, selectedItems));
+                break;
+            default:
+                content = null;
+                break;
+        }
+        return (
+            <section className="source-panel">
+                <div className="panel-header sp-font">Store list</div>
+                <div className="panel-main">
+                    <Input
+                        style={{ width: 454, margin: '12px 14px' }}
+                        prefix={<IconSearch />}
+                        onChange={onSearch}
+                        showClear
+                    />
+                    <div className="panel-controls sp-font">
+                        <span>Store to be selected: {filterData.length}</span>
+                        <Button onClick={onAllClick} theme="borderless" size="small">
+                            {allChecked ? 'Unselect all' : 'Select all'}
+                        </Button>
+                    </div>
+                    <div className="panel-list">{content}</div>
+                </div>
+            </section>
+        );
+    }
+
+    renderSelectedPanel(props) {
+        const { selectedData, onClear, clearText, onRemove, onSortEnd } = props;
+
+        let mainContent = null;
+
+        if (!selectedData.length) {
+            mainContent = <div className="empty sp-font">No data, please filter from the left</div>;
+        }
+
+        const SortableItem = SortableElement(item => this.renderItem('selected', item, onRemove));
+        const SortableList = SortableContainer(
+            ({ items }) => {
+                return (
+                    <div className="panel-main">
+                        {items.map((item, index) => (
+                            // sortableElement will take over the property 'key', so use another '_optionKey' to pass
+                            // otherwise you can't get `key` property in this.renderItem
+                            <SortableItem key={item.label} index={index} {...item} _optionKey={item.key}></SortableItem>
+                        ))}
+                    </div>
+                );
+            },
+            { distance: 10 }
+        );
+
+        mainContent = <SortableList useDragHandle onSortEnd={onSortEnd} items={selectedData}></SortableList>;
+
+        return (
+            <section className="selected-panel">
+                <div className="panel-header sp-font">
+                    <div>Selected sync store: {selectedData.length}</div>
+                    <Button theme="borderless" type="primary" onClick={onClear} size="small">
+                        {clearText || 'Clear '}
+                    </Button>
+                </div>
+                {mainContent}
+            </section>
+        );
+    }
+
+    render() {
+        const { dataSource } = this.state;
+        return (
+            <Transfer
+                defaultValue={[2, 4]}
+                onChange={values => console.log(values)}
+                className="component-transfer-demo-custom-panel"
+                renderSourcePanel={this.renderSourcePanel}
+                renderSelectedPanel={this.renderSelectedPanel}
+                dataSource={dataSource}
+            />
+        );
+    }
+}
+```
+
+### Tree Transfer
+
+The input type is `treeList`, and the [`Tree`](/en-US/navigation/tree) component is used as a custom rendering list. **v1.20.0 available**
+
+The properties of the default tree can be overridden by treeProps([TreeProps](/en-US/navigation/tree)). The default properties of the tree on the left are
+
+```ts
+interface Default TreeProps {
+    multiple:true,
+    disableStrictly:true,
+    leafOnly:true,
+    filterTreeNode:true,
+    searchRender:flase,
+
+}
+```
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                        {
+                            label: 'Chengdu',
+                            value: 'Chengdu',
+                            key: '0-0-2',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0',
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0',
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1',
+                },
+                {
+                    label: 'Mexico',
+                    value: 'Mexico',
+                    disabled: true,
+                    key: '1-2',
+                },
+                {
+                    label: 'Cuba',
+                    value: 'Cuba',
+                    key: '1-3',
+                },
+            ],
+        },
+    ];
+
+    const [v, $v] = useState(['Shanghai']);
+
+    return (
+        <div style={{ margin: 10, padding: 10, width: 600 }}>
+            <Transfer dataSource={treeData} type="treeList" value={v} onChange={$v}></Transfer>
+        </div>
+    );
+};
+```
+
+## API Reference
+
+### Trasnfer Props
+
+| props | description | data type | default | version |
+| --- | --- | --- | --- | --- |
+| className | Style class name | string | | |
+| dataSource | Data Source | Array<Item\>\|Array<GroupItem\>\|Array<TreeItem\> | [] | |
+| defaultValue | Default selected value | Array<string\|number> | | |
+| disabled | Whether to disable | boolean | false | |
+| draggable | Whether to enable drag sorting | boolean | false | |
+| emptyContent | Custom empty state prompt text, search is the text displayed when there are no search results, left is the text when there is no source data on the left, and right is the prompt text when no data is checked | {left: ReactNode; right: ReactNode; search: ReactNode;} | | |
+| filter | Custom filter logic, when false, the search box is not displayed | boolean \| (input:string, item: Item) => boolean | true | |
+| inputProps | Can be used to customize the search box Input, the configurable properties refer to the Input component | [InputProps](/en-US/input/input#Input) | | |
+| loading | Whether the left option is being loaded | boolean |-| |
+| onChange | The callback that is triggered when the selected value changes, and the callback is also triggered after the drag sort changes | (values: Array<string\|number>, items: Array<Item\>) => void | | |
+| onDeselect | Callback when unchecking | (item: Item) => void | | |
+| onSearch | Called when the input content of the search box changes | (inputValue: string) => void | | |
+| onSelect | Callback when checked | (item: Item) => void | | |
+| renderSelectedItem | Customize the rendering of a single selected item on the right | (item: {onRemove, sortableHandle} & Item) => ReactNode | | |
+| renderSelectedPanel | Customize the rendering of the selected panel on the right | (selectedPanelProps) => ReactNode | | 1.11.0 |
+| renderSourceItem | Customize the rendering of a single candidate item on the left | (item: {onChange, checked} & Item) => ReactNode | | |
+| renderSourcePanel | Customize the rendering of the left candidate panel | (sourcePanelProps) => ReactNode | | 1.11.0 |
+| showPath | When the type is `treeList`, control whether the selected item on the right shows the selection path | boolean | false | 1.20.0 |
+| style | Inline style | CSSProperties | | |
+| treeProps | When the type is `treeList`, it can be passed as TreeProps to the Tree component on the left | [TreeProps](/en-US/navigation/tree#Tree) | | 1.20.0 |
+| type | Transfer type, optional `list`, `groupList`, `treeList` | string |'list' | 1.20.0 |
+| value | The selected value, when the item is passed in, it will be used as a controlled component | Array<string\|number> | | |
+
+### Item Interface
+
+| props | description | data type | default | version |
+| --- | --- | --- | --- | --- |
+| className | Style class name | string | |
+| disabled | Whether to disable | boolean | false |
+| key | Required, unique identification of each option, no repetition is allowed | string \| number | |
+| label | Options display content | ReactNode | |
+| style | Inline style | CSSProperties | |
+| value | The value represented by the option | string \| number | |
+
+### GroupItem Interface
+
+GroupItem inherits all the properties of Item
+
+| props    | description           | data type                         | default | version |
+| -------- | --------------------- | --------------------------------- | ------- | ------- |
+| children | Elements of the group | array<Item\> |         |         |
+| title    | Group Name            | string                            |         |         |
+
+### TreeItem Interface
+
+TreeItem inherits all the properties of Item
+
+| props    | description    | data type        | default |
+| -------- | -------------- | ---------------- | ------- |
+| children | Children Items | array<TreeItem\> |         |
+
+## Design Tokens
+<DesignToken/>
+
+## Related materials
+
+```material
+52
+```

+ 948 - 0
content/input/transfer/index.md

@@ -0,0 +1,948 @@
+---
+localeCode: zh-CN
+order: 30
+category: 输入类
+title: Transfer 穿梭框
+icon: doc-transfer
+width: 60%
+dir: column
+brief: 一个更直观高效的多选选择器,可以露出更多选项的信息,支持搜索功能,缺点是占据更多空间
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Transfer } from '@douyinfe/semi-ui';
+```
+
+### 基本使用
+
+数据项需传入 value、label、key
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+
+() => {
+    const data = Array.from({ length: 100 }, (v, i) => {
+        return {
+            label: `选项名称 ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            dataSource={data}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### 分组
+
+将 type 设为 `groupList`
+
+分组的 dataSource,一级子元素必须拥有 title 以及 children 属性,结构参考 <GroupItem\>
+
+暂不支持多层嵌套
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+
+() => {
+    const dataWithGroup = [
+        {
+            title: '类别A',
+            children: [
+                { label: 'A-1', value: 1, disabled: false, key: 1 },
+                { label: 'A-2', value: 2, disabled: false, key: 2 },
+                { label: 'A-3', value: 3, disabled: false, key: 3 },
+            ],
+        },
+        {
+            title: '类别B',
+            children: [
+                { label: 'B-1', value: 4, disabled: false, key: 4 },
+                { label: 'B-2', value: 5, disabled: false, key: 5 },
+                { label: 'B-3(disabled)', value: 6, disabled: true, key: 6 },
+            ],
+        },
+        {
+            title: '类别C',
+            children: [
+                { label: 'C-1', value: 7, disabled: false, key: 7 },
+                { label: 'C-2', value: 8, disabled: false, key: 8 },
+                { label: 'C-3', value: 9, disabled: false, key: 9 },
+                { label: 'C-4', value: 10, disabled: false, key: 10 },
+                { label: 'C-5', value: 11, disabled: false, key: 11 },
+                { label: 'C-6', value: 12, disabled: false, key: 12 },
+                { label: 'C-7', value: 13, disabled: false, key: 13 },
+            ],
+        },
+    ];
+    return (
+        <Transfer
+            type="groupList"
+            defaultValue={[6]}
+            style={{ width: 568 }}
+            dataSource={dataWithGroup}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### 自定义筛选逻辑,自定义选项数据渲染
+
+使用`filter`自定义搜索逻辑,返回 true 时表示当前项符合筛选规则,保留当前项在列表中的显示,返回 false 则表示不符合,当前项会被隐藏  
+使用`renderSourceItem`,你可以自定义左侧每一条源数据的渲染结构  
+使用`renderSelectedItem` 你可以自定义右侧每一条已选项的渲染结构
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Checkbox, Avatar } from '@douyinfe/semi-ui';
+import { IconClose } from '@douyinfe/semi-icons';
+
+() => {
+    const renderSourceItem = item => {
+        return (
+            <div className="components-transfer-demo-source-item" key={item.label}>
+                <Checkbox
+                    onChange={() => {
+                        item.onChange();
+                    }}
+                    key={item.label}
+                    checked={item.checked}
+                    style={{ height: 52 }}
+                >
+                    <Avatar color={item.color} size="small">
+                        {item.abbr}
+                    </Avatar>
+                    <div className="info">
+                        <div className="name">{item.label}</div>
+                        <div className="email">{item.value}</div>
+                    </div>
+                </Checkbox>
+            </div>
+        );
+    };
+
+    const renderSelectedItem = item => {
+        return (
+            <div className="components-transfer-demo-selected-item" key={item.label}>
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div className="info">
+                    <div className="name">{item.label}</div>
+                    <div className="email">{item.value}</div>
+                </div>
+                <IconClose onClick={item.onRemove} />
+            </div>
+        );
+    };
+
+    const customFilter = (sugInput, item) => {
+        return item.value.includes(sugInput) || item.label.includes(sugInput);
+    };
+
+    const data = [
+        { label: '夏可漫', value: '[email protected]', abbr: '夏', color: 'amber', area: 'tiktok-US', key: 1 },
+        { label: '申悦', value: '[email protected]', abbr: '申', color: 'indigo', area: 'tiktok-UK', key: 2 },
+        { label: '文嘉茂', value: '[email protected]', abbr: '文', color: 'cyan', area: 'tiktok-HK', key: 3 },
+        { label: '曲晨一', value: '[email protected]', abbr: '曲', color: 'blue', area: 'vigo-India', key: 4 },
+        { label: '曲晨二', value: '[email protected]', abbr: '二', color: 'blue', area: 'vigo-India', key: 5 },
+        { label: '曲晨三', value: '[email protected]', abbr: '三', color: 'blue', area: 'vigo-India', key: 6 },
+    ];
+
+    return (
+        <Transfer
+            style={{ width: 568 }}
+            dataSource={data}
+            filter={customFilter}
+            defaultValue={['[email protected]', '[email protected]']}
+            renderSelectedItem={renderSelectedItem}
+            renderSourceItem={renderSourceItem}
+            inputProps={{ placeholder: '搜索姓名或邮箱' }}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+```css
+.components-transfer-demo-selected-item {
+    .semi-icon-close {
+        visibility: hidden;
+        color: var(--semi-color-tertiary);
+    }
+    &:hover {
+        .semi-icon-close {
+            visibility: visible;
+        }
+    }
+}
+
+.components-transfer-demo-selected-item,
+.components-transfer-demo-source-item {
+    height: 52px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 10px 12px;
+    &:hover {
+        background-color: var(--semi-color-fill-0);
+    }
+    .info {
+        margin-left: 8px;
+        flex-grow: 1;
+    }
+    .name {
+        font-size: 14px;
+        line-height: 20px;
+    }
+    .email {
+        font-size: 12px;
+        line-height: 16px;
+        color: var(--semi-color-text-2);
+    }
+}
+```
+
+### 禁用
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const data = Array.from({ length: 20 }, (v, i) => {
+        return {
+            label: `选项名称 ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            disabled
+            dataSource={data}
+            defaultValue={[2, 4]}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### 拖拽排序
+
+将 `draggable`设为 true,开启拖拽排序功能。v1.11.0 后支持
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+() => {
+    const data = Array.from({ length: 30 }, (v, i) => {
+        return {
+            label: `选项名称 ${i}`,
+            value: i,
+            disabled: false,
+            key: i,
+        };
+    });
+    return (
+        <Transfer
+            style={{ width: 568, height: 416 }}
+            dataSource={data}
+            defaultValue={[2, 4]}
+            draggable
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### 拖拽 + 自定义已选项渲染
+
+将 `draggable`设为 true,开启拖拽排序功能;使用 `renderSelectedItem` 自定义右侧已选项渲染;   
+你可以将触发器定义为任意你想要的ReactNode,并且添加样式。将拖拽触发器,使用 `sortableHandle` 进行包裹即可(sortableHandle于 v 1.22.0 后提供), 
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Checkbox, Avatar } from '@douyinfe/semi-ui';
+import { IconHandle, IconClose } from '@douyinfe/semi-icons';
+
+() => {
+    const renderSourceItem = item => {
+        return (
+            <div className="components-transfer-demo-source-item" key={item.label}>
+                <Checkbox
+                    onChange={() => {
+                        item.onChange();
+                    }}
+                    key={item.label}
+                    checked={item.checked}
+                    style={{ height: 52 }}
+                >
+                    <Avatar color={item.color} size="small">
+                        {item.abbr}
+                    </Avatar>
+                    <div className="info">
+                        <div className="name">{item.label}</div>
+                        <div className="email">{item.value}</div>
+                    </div>
+                </Checkbox>
+            </div>
+        );
+    };
+
+    const renderSelectedItem = item => {
+        const { sortableHandle } = item;
+        const DragHandle = sortableHandle(() => <IconHandle className={`semi-right-item-drag-handler`} />); 
+        return (
+            <div className="components-transfer-demo-selected-item" key={item.label}>
+                <DragHandle />
+                <Avatar color={item.color} size="small">
+                    {item.abbr}
+                </Avatar>
+                <div className="info">
+                    <div className="name">{item.label}</div>
+                    <div className="email">{item.value}</div>
+                </div>
+                <IconClose onClick={item.onRemove} />
+            </div>
+        );
+    };
+
+    const customFilter = (sugInput, item) => {
+        return item.value.includes(sugInput) || item.label.includes(sugInput);
+    };
+
+    const data = [
+        { label: '夏可漫', value: '[email protected]', abbr: '夏', color: 'amber', area: 'tiktok-US', key: 1 },
+        { label: '申悦', value: '[email protected]', abbr: '申', color: 'indigo', area: 'tiktok-UK', key: 2 },
+        { label: '文嘉茂', value: '[email protected]', abbr: '文', color: 'cyan', area: 'tiktok-HK', key: 3 },
+        { label: '曲晨一', value: '[email protected]', abbr: '曲', color: 'blue', area: 'vigo-India', key: 4 },
+        { label: '曲晨二', value: '[email protected]', abbr: '二', color: 'blue', area: 'vigo-India', key: 5 },
+        { label: '曲晨三', value: '[email protected]', abbr: '三', color: 'blue', area: 'vigo-India', key: 6 },
+    ];
+
+    return (
+        <Transfer
+            draggable
+            style={{ width: 568 }}
+            dataSource={data}
+            filter={customFilter}
+            defaultValue={['[email protected]', '[email protected]']}
+            renderSelectedItem={renderSelectedItem}
+            renderSourceItem={renderSourceItem}
+            inputProps={{ placeholder: '搜索姓名或邮箱' }}
+            onChange={(values, items) => console.log(values, items)}
+        />
+    );
+};
+```
+
+### 完全自定义渲染
+
+Semi 提供了 `renderSourcePanel`、`renderSelectedPanel` 入参,允许你完全自定义左右侧两个面板的渲染结构  
+通过该功能,你可以直接复用 Transfer 内部的逻辑能力,实现高度自定义样式结构的`Transfer`组件 `renderSourcePanel: (sourcePanelProps: SourcePanelProps) => ReactNode`  
+`SourcePanelProps`包含以下参数,你可以从中获取数据来渲染出你的 Panel 结构
+
+```ts
+interface SourcePanelProps {
+  value: Array<string|number>; // 所有选中项的key
+  loading: boolean;  // 是否加载中
+  noMatch: boolean;  // 是否没有符合当前搜索值匹配的项
+  filterData: Array<Item> // 匹配当前搜索值的项
+  sourceData: Array<Item>; // 所有项
+  allChecked: boolean; // 是否全部选中
+  showNumber: number; // 筛选结果数量
+  inputValue: string; // input搜索框的值
+  onSearch: (searchString: string) => any; // 搜索框变化时应调用的函数,入参为搜索值
+  onAllClick: () => void; // 左侧全部按钮点击时应调用的函数
+  onSelectOrRemove: (item: Item) => any; //选择、删除单个选项时应调用的函数,入参应为当前操作item
+  onSelect: (value:Array<string|number>)=>void; // 受控批量选中key
+  selectedItem: Map, // 所有已选项的集合
+}
+```
+
+`renderSelectedPanel: (selectedPanelProps: SelectedPanelProps) => ReactNode`  
+`SelectedPanelProps`包含以下参数
+
+```ts 
+interface SelectedPanelProps {
+  length: number; // 已选项的数量
+  onClear: () => void; // 点击清空时应调用的回调函数
+  onRemove: (item: Item) => void; // 删除单个选项时应调用的函数
+  onSortEnd: ({ oldIndex, newIndex}) => void; // 对结果重新排序时应调用的函数
+  selectedData: Array<Item>; // 所有已选项集合
+}
+```
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Transfer, Input, Spin, Button } from '@douyinfe/semi-ui';
+import { IconSearch } from '@douyinfe/semi-icons';
+
+class CustomRenderDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            dataSource: Array.from({ length: 100 }, (v, i) => ({
+                label: `海底捞门店 ${i}`,
+                value: i,
+                disabled: false,
+                key: i,
+            })),
+        };
+        this.renderSourcePanel = this.renderSourcePanel.bind(this);
+        this.renderSelectedPanel = this.renderSelectedPanel.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+    }
+
+    renderItem(type, item, onItemAction, selectedItems) {
+        let buttonText = '删除';
+        if (type === 'source') {
+            let checked = selectedItems.has(item.key);
+            buttonText = checked ? '删除' : '添加';
+        }
+        return (
+            <div className="semi-transfer-item panel-item" key={item.label}>
+                <p>{item.label}</p>
+                <Button
+                    theme="borderless"
+                    type="primary"
+                    onClick={() => onItemAction(item)}
+                    className="panel-item-remove"
+                    size="small"
+                >
+                    {buttonText}
+                </Button>
+            </div>
+        );
+    }
+
+    renderSourcePanel(props) {
+        const {
+            loading,
+            noMatch,
+            filterData,
+            selectedItems,
+            allChecked,
+            onAllClick,
+            inputValue,
+            onSearch,
+            onSelectOrRemove,
+        } = props;
+        let content;
+        switch (true) {
+            case loading:
+                content = <Spin loading />;
+                break;
+            case noMatch:
+                content = <div className="empty sp-font">{inputValue ? '无搜索结果' : '暂无内容'}</div>;
+                break;
+            case !noMatch:
+                content = filterData.map(item => this.renderItem('source', item, onSelectOrRemove, selectedItems));
+                break;
+            default:
+                content = null;
+                break;
+        }
+        return (
+            <section className="source-panel">
+                <div className="panel-header sp-font">门店列表</div>
+                <div className="panel-main">
+                    <Input
+                        style={{ width: 454, margin: '12px 14px' }}
+                        prefix={<IconSearch />}
+                        onChange={onSearch}
+                        showClear
+                    />
+                    <div className="panel-controls sp-font">
+                        <span>待选门店: {filterData.length}</span>
+                        <Button onClick={onAllClick} theme="borderless" size="small">
+                            {allChecked ? '取消全选' : '全选'}
+                        </Button>
+                    </div>
+                    <div className="panel-list">{content}</div>
+                </div>
+            </section>
+        );
+    }
+
+    renderSelectedPanel(props) {
+        const { selectedData, onClear, clearText, onRemove } = props;
+
+        let mainContent = selectedData.map(item => this.renderItem('selected', item, onRemove));
+
+        if (!selectedData.length) {
+            mainContent = <div className="empty sp-font">暂无数据,请从左侧筛选</div>;
+        }
+
+        return (
+            <section className="selected-panel">
+                <div className="panel-header sp-font">
+                    <div>已选同步门店: {selectedData.length}</div>
+                    <Button theme="borderless" type="primary" onClick={onClear} size="small">
+                        {clearText || '清空 '}
+                    </Button>
+                </div>
+                <div className="panel-main">{mainContent}</div>
+            </section>
+        );
+    }
+
+    render() {
+        const { dataSource } = this.state;
+        return (
+            <Transfer
+                onChange={values => console.log(values)}
+                className="component-transfer-demo-custom-panel"
+                renderSourcePanel={this.renderSourcePanel}
+                renderSelectedPanel={this.renderSelectedPanel}
+                dataSource={dataSource}
+            />
+        );
+    }
+}
+```
+
+```scss
+.component-transfer-demo-custom-panel {
+    .sp-font {
+        color: rgba(var(--semi-grey-9), 1);
+        font-size: 12px;
+        font-weight: 500;
+        line-height: 20px;
+    }
+    .empty {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+    .panel-item {
+        width: 176px;
+        height: 56px;
+        border-radius: 4px;
+        margin-bottom: 8px;
+        padding: 8px 12px;
+        flex-wrap: wrap;
+        background-color: rgba(22, 24, 35, 0.03);
+        &-main {
+            flex-grow: 1;
+        }
+        p {
+            margin: 0 12px;
+            flex-basis: 100%;
+        }
+        .panel-item-remove {
+            cursor: pointer;
+            color: var(--semi-color-primary);
+        }
+    }
+    .source-panel {
+        width: 482px;
+        height: 353px;
+        border: 1px solid var(--semi-color-border);
+        border-top: none;
+        .panel-list {
+            overflow-y: auto;
+            height: 202px;
+            display: flex;
+            margin-left: 12px;
+            margin-right: 12px;
+            flex-wrap: wrap;
+        }
+        .panel-controls {
+            margin: 10px 12px;
+            font-size: 12px;
+            line-height: 20px;
+            .semi-button {
+                margin-left: 8px;
+                font-size: 12px;
+            }
+        }
+        .panel-item {
+            margin-right: 8px;
+        }
+        margin-right: 16px;
+    }
+    .selected-panel {
+        width: 200px;
+        height: 353px;
+        .panel-main {
+            overflow-y: auto;
+            padding: 12px;
+            border: 1px solid var(--semi-color-border);
+            border-top: none;
+            height: 315px;
+            box-sizing: border-box;
+        }
+    }
+    .panel-header {
+        padding: 10px 12px;
+        border: 1px solid rgba(22, 24, 35, 0.16);
+        border-radius: 4px 4px 0 0;
+        height: 38px;
+        box-sizing: border-box;
+        background-color: var(--semi-color-tertiary-light-default);
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .clear {
+            cursor: pointer;
+            color: var(--semi-color-primary);
+        }
+    }
+}
+```
+
+### 完全自定义渲染 、 拖拽排序
+
+在完全自定义渲染的场景下,由于拖拽区的渲染也已由你完全接管,因此你不声明 draggable 亦可。  
+但你需要自行实现拖拽逻辑,我们推荐直接使用`react-sortable-hoc`  
+要支持拖拽排序,你需要在拖拽排序结束后,将 oldIndex、newIndex 作为入参,调用 onSortEnd
+
+```jsx live=true dir="column"
+import React from 'react';
+import { SortableContainer, SortableElement, sortableHandle } from 'react-sortable-hoc';
+import { Transfer, Button, Spin, Input } from '@douyinfe/semi-ui';
+import { IconHandle, IconSearch } from '@douyinfe/semi-icons';
+
+class CustomRenderDragDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            dataSource: Array.from({ length: 100 }, (v, i) => ({
+                label: `海底捞门店 ${i}`,
+                value: i,
+                disabled: false,
+                key: i,
+            })),
+        };
+        this.renderSourcePanel = this.renderSourcePanel.bind(this);
+        this.renderSelectedPanel = this.renderSelectedPanel.bind(this);
+        this.renderItem = this.renderItem.bind(this);
+    }
+
+    renderItem(type, item, onItemAction, selectedItems) {
+        let buttonText = '删除';
+        let newItem = item;
+
+        if (type === 'source') {
+            let checked = selectedItems.has(item.key);
+            buttonText = checked ? '删除' : '添加';
+        } else {
+            // delete newItem._optionKey;
+            newItem = { ...item, key: item._optionKey };
+            delete newItem._optionKey;
+        }
+
+        const DragHandle = sortableHandle(() => <IconHandle className="pane-item-drag-handler" />);
+
+        return (
+            <div className="semi-transfer-item panel-item" key={item.label}>
+                {type === 'source' ? null : <DragHandle />}
+                <div className="panel-item-main" style={{ flexGrow: 1 }}>
+                    <p>{item.label}</p>
+                    <Button
+                        theme="borderless"
+                        type="primary"
+                        onClick={() => onItemAction(newItem)}
+                        className="panel-item-remove"
+                        size="small"
+                    >
+                        {buttonText}
+                    </Button>
+                </div>
+            </div>
+        );
+    }
+
+    renderSourcePanel(props) {
+        const {
+            loading,
+            noMatch,
+            filterData,
+            selectedItems,
+            allChecked,
+            onAllClick,
+            inputValue,
+            onSearch,
+            onSelectOrRemove,
+        } = props;
+        let content;
+        switch (true) {
+            case loading:
+                content = <Spin loading />;
+                break;
+            case noMatch:
+                content = <div className="empty sp-font">{inputValue ? '无搜索结果' : '暂无内容'}</div>;
+                break;
+            case !noMatch:
+                content = filterData.map(item => this.renderItem('source', item, onSelectOrRemove, selectedItems));
+                break;
+            default:
+                content = null;
+                break;
+        }
+        return (
+            <section className="source-panel">
+                <div className="panel-header sp-font">门店列表</div>
+                <div className="panel-main">
+                    <Input
+                        style={{ width: 454, margin: '12px 14px' }}
+                        prefix={<IconSearch />}
+                        onChange={onSearch}
+                        showClear
+                    />
+                    <div className="panel-controls sp-font">
+                        <span>待选门店: {filterData.length}</span>
+                        <Button onClick={onAllClick} theme="borderless" size="small">
+                            {allChecked ? '取消全选' : '全选'}
+                        </Button>
+                    </div>
+                    <div className="panel-list">{content}</div>
+                </div>
+            </section>
+        );
+    }
+
+    renderSelectedPanel(props) {
+        const { selectedData, onClear, clearText, onRemove, onSortEnd } = props;
+
+        let mainContent = null;
+
+        if (!selectedData.length) {
+            mainContent = <div className="empty sp-font">暂无数据,请从左侧筛选</div>;
+        }
+
+        const SortableItem = SortableElement(item => this.renderItem('selected', item, onRemove));
+        const SortableList = SortableContainer(
+            ({ items }) => {
+                return (
+                    <div className="panel-main">
+                        {items.map((item, index) => (
+                            // sortableElement will take over the property 'key', so use another '_optionKey' to pass
+                            // otherwise you can't get `key` property in this.renderItem
+                            <SortableItem key={item.label} index={index} {...item} _optionKey={item.key}></SortableItem>
+                        ))}
+                    </div>
+                );
+            },
+            { distance: 10 }
+        );
+
+        mainContent = <SortableList useDragHandle onSortEnd={onSortEnd} items={selectedData}></SortableList>;
+
+        return (
+            <section className="selected-panel">
+                <div className="panel-header sp-font">
+                    <div>已选同步门店: {selectedData.length}</div>
+                    <Button theme="borderless" type="primary" onClick={onClear} size="small">
+                        {clearText || '清空 '}
+                    </Button>
+                </div>
+                {mainContent}
+            </section>
+        );
+    }
+
+    render() {
+        const { dataSource } = this.state;
+        return (
+            <Transfer
+                defaultValue={[2, 4]}
+                onChange={values => console.log(values)}
+                className="component-transfer-demo-custom-panel"
+                renderSourcePanel={this.renderSourcePanel}
+                renderSelectedPanel={this.renderSelectedPanel}
+                dataSource={dataSource}
+            />
+        );
+    }
+}
+```
+
+### 树穿梭框
+
+传入 type 为`treeList`,使用[`Tree`](/zh-CN/navigation/tree)组件作为自定义渲染列表。**v1.20.0 提供**
+
+可通过treeProps([TreeProps](/zh-CN/navigation/tree#Tree))来覆盖默认树的属性,左侧树默认属性为
+
+```
+{
+    multiple:true,
+    disableStrictly:true,
+    leafOnly:true,
+    filterTreeNode:true,
+    searchRender:flase,
+
+}
+```
+
+```jsx live=true dir="column"
+import React, { useState } from 'react';
+import { Transfer } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                        {
+                            label: 'Chengdu',
+                            value: 'Chengdu',
+                            key: '0-0-2',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0',
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0',
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1',
+                },
+                {
+                    label: 'Mexico',
+                    value: 'Mexico',
+                    disabled: true,
+                    key: '1-2',
+                },
+                {
+                    label: 'Cuba',
+                    value: 'Cuba',
+                    key: '1-3',
+                },
+            ],
+        },
+    ];
+
+    const [v, $v] = useState(['Shanghai']);
+
+    return (
+        <div style={{ margin: 10, padding: 10, width: 600 }}>
+            <Transfer dataSource={treeData} type="treeList" value={v} onChange={$v}></Transfer>
+        </div>
+    );
+};
+```
+
+## API 参考
+
+### Trasnfer Props
+
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| className | 样式类名 | string |  |  |
+| dataSource | 数据源 | Array<Item\>\|Array<GroupItem\>\|Array<TreeItem\> | [] |  |
+| defaultValue | 默认已选中值 | Array<string\|number> | |  |
+| disabled | 是否禁用 | boolean | false |  |
+| draggable | 是否开启拖拽排序 | boolean | false |  |
+| emptyContent | 自定义空状态的提示文本,search 为无搜索结果时展示的文本,left 为左侧无源数据时的文本,right 为无勾选数据时的提示文本 | {left: ReactNode; right: ReactNode; search: ReactNode;} |  |  |
+| filter | 自定义筛选逻辑, 当为 false 时,不展示搜索框 | boolean \| (input:string, item: Item) => boolean | true |  |
+| inputProps | 可用于自定义搜索框 Input,可配置属性参考 Input 组件 | [InputProps](/zh-CN/input/input#API%20%E5%8F%82%E8%80%83) |  |  |
+| loading | 是否正在加载左侧选项 | boolean | - |  |
+| onChange | 选中值发生变化时触发的回调, 拖拽排序变化后也会触发该回调 | (values: Array<string\|number>, items: Array<Item\>) => void |  |  |
+| onDeselect | 取消勾选时的回调 | (item: Item) => void | |  |
+| onSearch | 搜索框输入内容变化时调用 | (inputValue: string) => void | |  |
+| onSelect | 勾选时的回调 | (item: Item) => void | |  |
+| renderSelectedItem | 自定义右侧单个已选项的渲染 | (item: { onRemove, sortableHandle } & Item) => ReactNode |  |  |
+| renderSelectedPanel | 自定义右侧已选面板的渲染 | (selectedPanelProps) => ReactNode |  | 1.11.0 |
+| renderSourceItem | 自定义左侧单个候选项的渲染 | (item: { onChange, checked } & Item) => ReactNode |  |  |
+| renderSourcePanel | 自定义左侧候选面板的渲染 | (sourcePanelProps) => ReactNode |  | 1.11.0 |
+| showPath | 当 type 为`treeList`时,控制右侧选中项是否显示选择路径 | boolean | false | 1.20.0 |
+| style | 内联样式 | CSSProperties |  |  |
+| treeProps | 当 type 为`treeList`时,可作为 TreeProps 传入左侧的 Tree 组件 | [TreeProps](/zh-CN/navigation/tree#Tree) | | 1.20.0 |
+| type | Transfer 类型,可选`list`,`groupList`,`treeList` | string | 'list' | 1.20.0 |
+| value | 已选中值,传入该项时,将作为受控组件使用 | Array<string\|number> |  |  |
+
+### Item Interface
+
+| 属性      | 说明                                 | 类型             | 默认值 |
+| --------- | ------------------------------------ | ---------------- | ------ |
+| className | 样式类名                             | string           |        |
+| disabled  | 是否禁用                             | boolean          | false  |
+| key       | 必填,每个选项的唯一标识,不允许重复 | string \| number          |        |
+| label     | 选项展示内容                         | ReactNode        |        |
+| style     | 内联样式                             | CSSProperties           |        |
+| value     | 选项代表的值                         | string \| number |        |
+
+### GroupItem Interface
+
+GroupItem继承Item的所有属性
+
+| 属性     | 说明         | 类型                              | 默认值 |
+| -------- | ------------ | --------------------------------- | ------ |
+| children | 该分组的元素 | Array<Item\> |        |
+| title    | 分组名称     | string                            |        |
+
+### TreeItem Interface
+
+TreeItem 继承 Item 的所有属性
+
+| 属性     | 说明   | 类型             | 默认值 |
+| -------- | ------ | ---------------- | ------ |
+| children | 子元素 | Array<TreeItem\> |        |
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+
+```material
+52
+``` -->

+ 1263 - 0
content/input/treeselect/index-en-US.md

@@ -0,0 +1,1263 @@
+---
+localeCode: en-US
+order: 31
+category: Input
+title:  TreeSelect
+subTitle: TreeSelect
+icon: doc-treeselect
+brief: A tree view component for selection.
+---
+
+
+## When to Use
+
+When the options to select is in tree structure, you could use TreeSelect, e.g. department hierarchy, subject system, category directory and etc.
+
+## Demos
+
+### How to import
+
+```jsx import
+import { TreeSelect } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+By default, TreeSelect is in single select mode and each item is selectable.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: 'Beijing',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: 'Shanghai',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return (
+    <TreeSelect
+      style={{ width: 300 }}
+      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      treeData={treeData}
+      placeholder="Please select"
+    />
+  )
+}
+```
+
+### Multi-choice
+
+You could use `multiple` to set mode to multi-choice. When all child items are selected, the parent item will be selected. Use `maxTagCount` to set the cap number of tags displayed. Use `leafOnly` (>= v0.32.0) if you prefer to render leaf nodes only and the corresponding params for onChange will also be leaf nodes values.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: 'Beijing',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: 'Shanghai',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                    {
+                        label: 'Chengdu',
+                        value: 'Chengdu',
+                        key: '0-0-2',
+                    },
+                ],
+            },
+            {
+                label: 'Japan',
+                value: 'Japan',
+                key: '0-1',
+                children: [
+                    {
+                        label: 'Osaka',
+                        value: 'Osaka',
+                        key: '0-1-0'
+                    }
+                ]
+            },
+        ],
+    },
+    {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+        children: [
+            {
+                label: 'United States',
+                value: 'United States',
+                key: '1-0'
+            },
+            {
+                label: 'Canada',
+                value: 'Canada',
+                key: '1-1'
+            }
+        ]
+    }
+  ];
+  return (
+    <div>
+      <TreeSelect
+        style={{ width: 300 }}
+        multiple
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        placeholder="Please select"
+      />
+      <br/>
+      <br/>
+      <TreeSelect
+        style={{ width: 300 }}
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        multiple
+        maxTagCount={2}
+        placeholder="Display at most two tags"
+      />
+      <br/>
+      <br/>
+      <TreeSelect
+        style={{ width: 300 }}
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        multiple
+        leafOnly
+        placeholder="Display leaf nodes only"
+      />
+    </div>
+  )
+}
+```
+
+### Searchable
+
+Use `filterTreeNode` to support search input. By default it searches the `label` property of the data. You can use `treeNodeFilterProp` to set another property to search or pass in a function to `filterTreeNode` to customize search behavior.
+
+You could also use `showFilteredOnly` if you prefer to display filtered results only.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect, Switch } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            showFilteredOnly: false,
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(showFilteredOnly) {
+        this.setState({ showFilteredOnly });
+    }
+    render() {
+        const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0'
+                        }
+                    ]
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0'
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1'
+                }
+            ]
+        }
+    ];
+    const { showFilteredOnly } = this.state;
+    return (
+        <>
+        <span>showFilteredOnly</span>
+        <Switch
+            checked={showFilteredOnly}
+            onChange={this.onChange}
+            size="small"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            filterTreeNode
+            showFilteredOnly={showFilteredOnly}
+            placeholder="Single Searchable TreeSelect"
+            searchPlaceholder="Start searching"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            filterTreeNode
+            maxTagCount={2}
+            showFilteredOnly={showFilteredOnly}
+            placeholder="Multiple Searchable TreeSelect"
+            searchPlaceholder="Start searching"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            filterTreeNode
+            maxTagCount={2}
+            showFilteredOnly={showFilteredOnly}
+            placeholder="search input autofocus"
+            searchPlaceholder="autofocus"
+            searchAutoFocus
+        />
+        </>
+    )
+    }
+}
+```
+
+
+### Search Box Position
+
+You can use `searchPosition` to set the position of the search box, optional: `dropdown` (default), `trigger`.
+
+When the input box is at trigger:
+1. The placeholder of the search box is controlled by `placeholder`;
+2. When `showClear=true`, click the clear button of the input box, the inputValue and value will be cleared at the same time.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0'
+                        }
+                    ]
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0'
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1'
+                }
+            ]
+        }
+    ];
+    return (
+        <>
+            <TreeSelect
+                searchPosition="trigger"
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                filterTreeNode
+                placeholder="Single selection"
+            />
+            <br />
+            <br />
+            <TreeSelect
+                searchPosition="trigger"
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                multiple
+                filterTreeNode
+                maxTagCount={2}
+                placeholder="Multiple selection"
+            />
+        </>
+    );
+}
+```
+
+### Size
+
+You can set the size by `size`, one of: 'small'、'default'、'large'
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0'
+                        }
+                    ]
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0'
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1'
+                }
+            ]
+        }
+    ];
+  return ( 
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="small"
+            placeholder="small"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="default"
+            placeholder="default"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="large"
+            placeholder="large"
+        />
+    </div>
+  )
+}
+```
+
+### Disabled
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: 'Beijing',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: 'Shanghai',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return (
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disabled
+            placeholder="Disabled TreeSelect"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            defaultValue={'Shanghai'}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disabled
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            defaultValue={['Shanghai', 'North America']}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            disabled
+        />
+    </div>
+  )
+}
+```
+
+
+### Disable Strictly
+
+version: >= 1.30.0
+
+You can use `disableStrictly` to enable strict disabling. After enabling strict disabling, when the node is disabled, the selected state cannot be changed through the relationship between the child or the parent.
+
+Take the following demo as an example, the node "China" is strictly disabled. Therefore, when we change the selected state of its parent node "Asia", it will not affect the selected state of the node "China".
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                disable: true,
+                children: [
+                    {
+                        label: 'Beijing',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: 'Shanghai',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+            {
+                label: 'Japan',
+                value: 'Japan',
+                key: '0-1',
+            },
+        ],
+    },
+    {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return ( 
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disableStrictly
+            multiple
+            defaultValue={['Shanghai']}
+        />
+    </div>
+  )
+}
+```
+
+### Default Expand All
+
+Both `defaultExpandAll` and `expandAll` can set the default expanded/collapsed state of `TreeSelect`. The difference between the two is that `defaultExpandAll` only takes effect during initialization, while `expandAll` will take effect not only during initialization, but also when the data (`treeData`) is dynamically updated.
+
+Among them, `expandAll` is supported starting from 1.30.0.
+
+In the demo below, after `TreeData` is updated, `defaultExpandAll` becomes invalid, and `expandAll` still takes effect.
+
+```jsx live=true
+import React, { useState, useEffect } from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+        }
+    ];
+
+    const [data, setData] = useState([]);
+
+    useEffect(() => {
+        setTimeout(() => setData(treeData), 500)
+    }, []);
+
+    return (
+        <>
+            <TreeSelect
+                style={{ width: 300, marginBottom: 20 }}
+                expandAll
+                treeData={data}
+                placeholder="expandAll"
+            />
+            <TreeSelect
+                style={{ width: 300 }}
+                defaultExpandAll
+                treeData={data}
+                placeholder="defaultExpandAll"
+            />
+        </>
+    )
+}
+```
+
+### Controlled Component
+
+You can use `value` along with `onChange` property if you want to use TreeSelect as a controlled component.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: 'Shanghai'
+        };
+    }
+    onChange(value) {
+        this.setState({value})
+    }
+    render() {
+        const treeData = [
+            {
+                label: 'Asia',
+                value: 'Asia',
+                key: '0',
+                children: [
+                    {
+                        label: 'China',
+                        value: 'China',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: 'Beijing',
+                                value: 'Beijing',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: 'Shanghai',
+                                value: 'Shanghai',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: 'North America',
+                value: 'North America',
+                key: '1',
+            }
+        ];
+        return (
+            <TreeSelect
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                value={this.state.value}
+                placeholder="Please select"
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+### Virtualized TreeSelect
+If you need to render large sets of tree structured data, you could use virtualized tree. In virtualized mode, animation / motion is disabled for better performance. 
+
+The property `virtualize` is an object consisting of the following values: 
+- height: Height of the dropDown, If passed in as a string, computed height should not be zero for render purpose, in other words, parent node should have offsetHeight. Pass in a number recommended.
+- width: Width of the dropDown.
+- itemSize: Height for each line of treeNode, required
+
+If tree is searchable, you could also set `showFilteredOnly={true}` to reduce time of rendering for results.
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            gData: [],
+            total: 0,
+        }
+        this.onGen = this.onGen.bind(this);
+    }
+
+    generateData(x = 5, y = 4, z = 3, gData = []) {
+        // x:number of nodes
+        // y:number of nodes with children in each level
+        // z:number of level
+        function _loop(_level, _preKey, _tns) {
+            const preKey = _preKey || '0';
+            const tns = _tns || gData;
+
+            const children = [];
+            for (let i = 0; i < x; i++) {
+                const key = `${preKey}-${i}`;
+                tns.push({ label: `${key}-label`, key: `${key}-key`, value: `${key}-value` });
+                if (i < y) {
+                    children.push(key);
+                }
+            }
+            if (_level < 0) {
+                return tns;
+            }
+            const __level = _level - 1;
+            children.forEach((key, index) => {
+                tns[index].children = [];
+                return _loop(__level, key, tns[index].children);
+            });
+
+            return null;
+        }
+        _loop(z);
+        
+        function calcTotal(x, y, z) {
+            const rec = n => (n >= 0 ? x * y ** n-- + rec(n) : 0);
+            return rec(z + 1);
+        }
+        return {gData, total: calcTotal(x, y, z)};
+    }
+
+      
+    onGen() {
+        const { gData, total } = this.generateData();
+        this.setState({
+            gData,
+            total
+        });
+    };
+  
+    render() {
+      return (
+        <div style={{ padding: '0 20px' }}>
+          <Button onClick={this.onGen}>Generate Data: </Button>
+          <span>In total: {this.state.total}</span>
+          <br/>
+          <br/>
+          {this.state.gData.length ? (
+                <TreeSelect
+                  style={{ width: 300 }}
+                  treeData={this.state.gData}
+                  filterTreeNode
+                  showFilteredOnly
+                  placeholder="Please select"
+                  dropdownStyle={{ 
+                      overflow: 'hidden'
+                    }}
+                  virtualize={{
+                    itemSize: 28,
+                    // dropDown height 300 minus search box height minus padding 8 * 2
+                    // or if you set dropDown height, it will automatically fill rest space
+                    height: 236                
+                  }}
+            />
+          ) : null}
+        </div>
+      );
+    }
+}
+```
+
+### Dynamic Update of Data
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            treeData: [],
+        }
+        this.add = this.add.bind(this);
+    }
+    add() {
+        let itemLength = Math.floor(Math.random() * 5) + 1;
+        let treeData = new Array(itemLength).fill(0).map((v, i) => {
+            let length = Math.floor(Math.random() * 3);
+            let children = new Array(length).fill(0).map((cv, ci) => {
+                let child = {
+                    key: `${i}-${ci}`,
+                    label: `Leaf-${i}-${ci}`,
+                    value: `${i}-${ci}`
+                }
+                return child;
+            });
+            let item = {
+                key: `${i}`,
+                label: `Item-${i}`,
+                value: `${i}`,
+                children
+            };
+            return item;
+        })
+        this.setState({ treeData });
+    }
+    render() {
+        return (
+            <>
+                <TreeSelect
+                    style={{ width: 300 }}
+                    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                    treeData={this.state.treeData}
+                    placeholder="Please select"
+                />
+                <br/>
+                <br/>
+                <Button onClick={this.add}>
+                    Update Data
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### Load Data Asynchronously
+You could use `loadData` to load treeData asynchronously on node expansion. Notice `isLeaf` is required to mark node as leaf in treeData.
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+    const initialData = [
+        {
+            label: 'Expand to load',
+            value: '0',
+            key: '0',
+        },
+        {
+            label: 'Expand to load',
+            value: '1',
+            key: '1',
+        },
+        {
+            label: 'Leaf Node',
+            value: '2',
+            key: '2',
+            isLeaf: true,
+        },
+    ];
+    const [treeData, setTreeData] = useState(initialData);
+
+    function updateTreeData(list, key, children) {
+        return list.map(node => {
+            if (node.key === key) {
+                return { ...node, children };
+            }
+            if (node.children) {
+                return { ...node, children: updateTreeData(node.children, key, children) };
+            }
+            return node;
+        });
+    }
+
+    function onLoadData({ key, children }) {
+        return new Promise(resolve => {
+            if (children) {
+                resolve();
+                return;
+            }
+            setTimeout(() => {
+                setTreeData(origin =>
+                    updateTreeData(origin, key, [
+                        {
+                            label: 'Child Node',
+                            key: `${key}-0`,
+                        },
+                        {
+                            label: 'Child Node',
+                            key: `${key}-1`,
+                        },
+                    ]),
+                );
+                resolve();
+            }, 1000);
+        });
+    }
+    return (
+        <TreeSelect
+            loadData={onLoadData}
+            treeData={treeData}
+            style={{ width: 300 }}
+            placeholder="Please select"
+        />
+    );
+};
+```
+
+### Custom Trigger
+
+If the default trigger style cannot meet your needs, you can use `triggerRender` to customize the display of the select box.
+
+The triggerRender input is as follows:
+
+```typescript
+interface triggerRenderProps {
+    componentProps: TreeSelectProps;// TreeSelect props
+    disabled: boolean;              // disabled status
+    value: TreeNode[];              // data of the selected node
+    inputValue: string;             // value of the input box
+    onClear: e => void;             // onClear function
+    placeholder: string;            // placeholder
+}
+```
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+            {
+                label: 'Asia',
+                value: 'Asia',
+                key: '0',
+                children: [
+                    {
+                        label: 'China',
+                        value: 'China',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: 'Beijing',
+                                value: 'Beijing',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: 'Shanghai',
+                                value: 'Shanghai',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: 'North America',
+                value: 'North America',
+                key: '1',
+            }
+        ], []);
+    const onChange = useCallback((val) => {
+        setValue(val);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setValue([]);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return value && value.length ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [value]);
+
+    return (
+        <TreeSelect
+            onChange={onChange}
+            style={{ width: 300 }}
+            value={value}
+            multiple
+            treeData={treeData}
+            placeholder='Custom Trigger'
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                    {value && value.length ? value.join(', ') : placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+### Custom Rendering Selected Item
+
+You can use renderSelectedItem to customize the rendering structure of the selected item in the selection box.
+
+- In not multiple mode: `renderSelectedItem(treeNode:TreeNode) => content:ReactNode`
+- In multiple mode: `renderSelectedItem(treeNode:TreeNode, { index:number, onClose:function }) => { isRenderInTag:bool, content:ReactNode }`
+    - When isRenderInTag is true, content wraps are automatically rendered in the Tag (with background color and close button)
+    - When isRenderInTag is false, the returned content will be rendered directly
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { TreeSelect, Tag } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+      {
+          label: 'Asia',
+          value: 'Asia',
+          key: '0',
+          children: [
+              {
+                  label: 'China',
+                  value: 'China',
+                  key: '0-0',
+                  children: [
+                      {
+                          label: 'Beijing',
+                          value: 'Beijing',
+                          key: '0-0-0',
+                      },
+                      {
+                          label: 'Shanghai',
+                          value: 'Shanghai',
+                          key: '0-0-1',
+                      },
+                  ],
+              },
+          ],
+      },
+      {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+      },
+      {
+        label: 'South America',
+        value: 'South America',
+        key: '2',
+      },
+      {
+        label: 'Antarctica',
+        value: 'Antarctica',
+        key: '3',
+      },
+    ], []);
+    
+    return (
+        <>
+            <h4>Single TreeSelect</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                renderSelectedItem={item => item.label}
+            />
+            <h4>Multiple + isRenderInTag=true</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                multiple
+                renderSelectedItem={(item, { index, onClose }) => ({ content: item.label, isRenderInTag: true })}
+            />
+            <h4>Multiple + isRenderInTag=false</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                multiple
+                maxTagCount={2}
+                renderSelectedItem={(item, { index, onClose }) => ({ content: <Tag key={index} color="white">{item.value}</Tag>, isRenderInTag: false })}
+            />
+        </>
+    );
+}
+```
+
+## API Reference
+
+### TreeSelect
+
+| Properties               | Instructions                                                                        | type                                                              | Default     | Version |
+| ------------------------ | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------- | ------- |
+| arrowIcon|Customize the right drop-down arrow Icon, when the showClear switch is turned on and there is currently a selected value, hover will give priority to the clear icon| ReactNode | | 1.15.0|
+|autoAdjustOverflow|Whether the pop-up layer automatically adjusts the direction when it is obscured (only vertical direction is supported for the time being, and the inserted parent is body)|boolean | true| 0.34.0|
+| autoExpandParent | Toggle whether to expand parent nodes automatically | boolean | false | 0.34.0 |
+| className                | Class name                                                                          | string                                                            | -           | -       |
+| clickToHide  | Whether to close the drop-down layer automatically when selecting, only works in single-selection mode  | boolean    | true | 1.5.0      |
+| defaultExpandAll    | Set whether to expand all nodes during initialization. And if the data (`treeData`) changes, this api cannot affect the expansion of the node. If you need this, you can use `expandAll`    | boolean                     | false   | 0.32.0 |
+| defaultExpandedKeys | Keys of default expanded nodes. Direct child nodes will be displayed. | string\[] | - | 0.32.0 |
+| defaultOpen | Toggle whether to open dropdown menu by defaultt | boolean | false | 0.32.0 |
+| defaultValue             | Default value                                                                       | string \| number \| TreeNode \| (string \| number \| TreeNode)[]                                                  | -           | -       |
+| disabled                 | Disabled                                                                            | boolean                                                           | false       | -       |
+| disableStrictly | Disable Strictly | boolean | false | 1.30.0 |
+| dropdownClassName        | `className` property for dropDown                                                   | string                                                            | -           | -       |
+| dropdownMatchSelectWidth | Toggle if min-width of dropDown menu should be same as width of select box          | boolean                                                           | true        | -       |
+| dropdownStyle            | Style for dropDown                                                                  | CSSProperties                                                            | -           | -       |
+| emptyContent             | Empty content when no data                                                          | ReactNode                                                         | `no result` | -       |
+| expandAction             | Expand logic, one of false, 'click', 'doubleClick'. Default is set to false, which means item will not be expanded on clicking except on expand icon    | boolean \| string   | false | 1.4.0        |
+| expandAll | Set whether to expand all nodes by default. If the data (`treeData`) changes, the default expansion will still be affected by this api | boolean | false | 1.30.0 |
+| expandedKeys        | (Controlled)Keys of expanded nodes. Direct child nodes will be displayed.  | string[]                    | -       | 0.32.0 |
+| filterTreeNode           | Toggle whether searchable or pass in a function to customize search behavior.       | boolean\|(inputValue: string, treeNodeString: TreeNodeString) => boolean | false       | -       |
+| getPopupContainer        | Container to render pop-up level, you need to set 'position: relative`                                                    | function():HTMLElement                                            | -           | -       |
+| insetLabel               | Prefix alias,used mainly in Form                                                   | ReactNode                                                         | -           | 0.28.0  |
+| labelEllipsis | Toggle whether to ellipsis label when overflow | boolean | false\|true(virtualized) | 1.8.0 |  
+| leafOnly | Toggle whether to display tags for leaf nodes only and for onChange callback parms in multiple mode | boolean | false |0.32.0 |
+| loadData | Load data asynchronously and the return value should be a promise | (treeNode: TreeNode) => Promise |-| 1.32.0|
+| loadedKeys | (Controlled)Mark node as loaded, working with `loadData` | Set< string > | - | 1.32.0|
+| maxTagCount              | Maximum number of tags displayed                                                    | number                                                            | -           | -       |
+| motionExpand             | Toggle whether to turn on animation for expansion                                   | boolean                                                           | true        | -       |
+| multiple                 | Toggle whether in multi-choice mode                                                 | boolean                                                           | false       | -       |
+| optionListStyle | Style for optionList  | CSSProperties | - | 1.8.0 |
+| outerBottomSlot          | Rendered at the bottom of the pop-up layer, custom slot level with optionList    | ReactNode  |  - | 1.1.0|
+| outerTopSlot| Rendered at the top of the pop-up layer, custom slot level with optionList. If turn on filterTreeNode, it will replace search box as well. You could use static search method to customize instead. |  ReactNode  |  - | 1.9.0|
+| placeholder              | Placeholder for input box                                                           | string                                                            | -           | -       |
+| prefix                   | Prefix                                                                              | ReactNode                                                         | -           | 0.28.0  |
+| renderFullLabel | Custom option render function, [Detailed Params and Usage](/en-US/navigation/tree#Advanced%20FullRender) | (obj) => ReactNode | 1.7.0 |
+| renderLabel | Custom label render function | (label:ReactNode, data:TreeNode) => ReactNode | 1.6.0 | 
+| renderSelectedItem | render selected item | Function | - | 1.26.0 | 
+| searchAutoFocus        | Whether autofocus for search box           | boolean      | false           | 1.27.0       |
+| searchPlaceholder        | Placeholder for search box                                                          | string                                                            | -           | -       |
+| searchPosition | Set the position of the search box, one of: `dropdown`、`trigger` | string | `dropdown` | 1.29.0 |
+| showClear | When the value is not empty, whether the trigger displays the clear button | boolean | false |  |
+| showFilteredOnly | Toggle whether to displayed filtered result only in search mode | boolean | false | 0.32.0 |
+| showSearchClear | Toggle whether to support clear search box | boolean | true | 0.35.0 |
+| size                     | Size for input box,one of `large`,`small`,`default`                              | string                                                            | `default`   | -       |
+| style                    | Inline style                                                                        | CSSProperties                                                            | -           | -       |
+| suffix                   | Suffix                                                                              | ReactNode                                                         | -           | 0.28.0  |
+| treeData                 | Data for treeNodes                                                                  | TreeNode[]                                                  | \[]         | -       |
+| treeNodeFilterProp       | Property in a `treeNode` used to search                                             | string                                                            | `label`     | -       |
+| treeNodeLabelProp        | Property in a `treeNode` used to display                                            | string                                                            | `label`     | -       |
+| triggerRender | Method to create a custom trigger  | ({ placeholder: string }) => ReactNode | - | 0.34.0 |
+| validateStatus | Validate status,one of `warning`、`error`、 `default`, only affects the background color of the component | string | - | 0.32.0 |
+| value                    | Value data of current item, used when TreeSelect is a controlled component                       | string \| number \| TreeNode \| (string \| number \| TreeNode)[]                                                  | -           | -       |
+| virtualize | Efficiently rendering large lists, refer to Tree - VirtualizeObj. Motion is disabled when tree is rendered as virtualized list. | object | - | 0.32.0 |
+| zIndex | zIndex for treeSelect dropDown menu | number | 1030 | 0.30.0 |
+| onBlur                 | Callback function when treeSelect blur | function(event)                            | -           | -       |
+| onFocus                 | Callback function when treeSelect focus  | function(event)                            | -           | -       |
+| onChange                 | Callback function when the tree node is selected, return the value property of data | Function                           | -           | -       |
+| onChangeWithObject        | Toggle whether to return all properties in an option as a return value. When set to true, onChange turn to Function(node, e)   | boolean                     | false   | 1.0.0 |
+| onExpand                 | Callback function when expand or collapse a node                                    | function(expandedKeys:array, {expanded: bool, node})              | -           | -       |
+| onLoad | Callback function when a node is loaded | (loadedKeys: Set< string >, treeNode: TreeNode) => void | - | 1.32.0|
+| onSearch                 | Callback function when search value changes                                         | function(sugInput: string)                                        | -           | -       |
+| onSelect                 | Callback function when selected, return the key property of data                    | function(selectedKey:string, selected: bool, selectedNode: TreeNode)                      | -           | -       |
+| onVisibleChange     | A callback triggered when the pop-up layer is displayed/hidden   | function(isVisble:boolean) |     |   1.4.0  |
+
+### TreeNode
+
+> **Key for `TreeNode` is required and must be unique**, `label` can be duplicated. Before **v>=1.7.0** value is also required and must be unique.
+> After **v>=1.7.0**, value is not required. In this case, the value property in `onChange`, `value`, `defaultValue` and `onChangeWithObject` will point to key property.
+> To ensure everything behave as expected, keep a consistency of whether to have value or not to have value.
+
+| Properties | Instructions| type              | Default |
+| ---------- | ------------------------------------------- | ----------------- | ------- |
+| value      | Value| string\|number           | -       |
+| label      | Displayed label    | string\|ReactNode | -       |
+| icon       | Icon | ReactNode         | -       |
+| disabled   | Disabled, supported in multiple select mode | boolean           | false   |
+| key        | Required and must be unique                 | string            | -       |
+| isLeaf     | Whether it is a leaf node | boolean |-|
+
+### Method
+- search(sugInput: string)
+For custom rendering of input box.
+
+## Design Tokens
+<DesignToken/>

+ 1243 - 0
content/input/treeselect/index.md

@@ -0,0 +1,1243 @@
+---
+localeCode: zh-CN
+order: 31
+category: 输入类
+title: TreeSelect 树选择器
+icon: doc-treeselect
+brief: 树型选择组件。
+---
+
+## 何时使用
+
+类似 Select 的选择控件,可选择的数据结构是一个树形结构时,可以使用 TreeSelect,例如公司层级、学科系统、分类目录等等。
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { TreeSelect } from '@douyinfe/semi-ui';
+```
+### 基本用法
+
+最简单的用法,默认为单选模式,每一级菜单项均可选择。
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+() => {
+  const treeData = [
+    {
+        label: '亚洲',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: '中国',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: '北京',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: '上海',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+        ],
+    },
+    {
+        label: '北美洲',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return ( 
+    <TreeSelect
+      style={{ width: 300 }}
+      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      treeData={treeData}
+      placeholder="请选择"
+    />
+  )
+}
+```
+
+### 多选
+
+设置 `multiple`,可以进行多选。多选情况下所有子项都被选择时,自动勾选显示其父项。通过设置 `maxTagCount` 属性,可以设置显示的标签数量上限。通过设置 `leafOnly` (>= v0.32.0) 属性,可以设置只展示叶子节点,同时 onChange 的回调入参也会只有叶子节点的值。
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+() => {
+  const treeData = [
+    {
+        label: 'Asia',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: 'China',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: 'Beijing',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: 'Shanghai',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                    {
+                        label: 'Chengdu',
+                        value: 'Chengdu',
+                        key: '0-0-2',
+                    },
+                ],
+            },
+            {
+                label: 'Japan',
+                value: 'Japan',
+                key: '0-1',
+                children: [
+                    {
+                        label: 'Osaka',
+                        value: 'Osaka',
+                        key: '0-1-0'
+                    }
+                ]
+            },
+        ],
+    },
+    {
+        label: 'North America',
+        value: 'North America',
+        key: '1',
+        children: [
+            {
+                label: 'United States',
+                value: 'United States',
+                key: '1-0'
+            },
+            {
+                label: 'Canada',
+                value: 'Canada',
+                key: '1-1'
+            }
+        ]
+    }
+  ];
+  return ( 
+    <div>
+      <TreeSelect
+        style={{ width: 300 }}
+        multiple
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        placeholder="请选择"
+      />
+      <br/>
+      <br/>
+      <TreeSelect
+        style={{ width: 300 }}
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        multiple
+        maxTagCount={2}
+        placeholder="当选中标签超过两个将折叠"
+      />
+      <br/>
+      <br/>
+      <TreeSelect
+        style={{ width: 300 }}
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        treeData={treeData}
+        multiple
+        leafOnly
+        placeholder="只渲染叶子节点"
+      />
+    </div>
+  )
+}
+```
+
+### 可搜索的
+
+通过设置 `filterTreeNode` 属性可支持搜索功能。默认对 `label` 值进行搜索,可通过 `treeNodeFilterProp` 更改。
+
+如果只希望展示过滤后的结果,可以设置 `showFilteredOnly` 。
+```jsx live=true
+import React from 'react';
+import { TreeSelect, Switch } from '@douyinfe/semi-ui';
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            showFilteredOnly: false,
+        }
+        this.onChange = this.onChange.bind(this);
+    }
+    onChange(showFilteredOnly) {
+        this.setState({ showFilteredOnly });
+    }
+    render() {
+        const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0'
+                        }
+                    ]
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0'
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1'
+                }
+            ]
+        }
+    ];
+    const { showFilteredOnly } = this.state;
+    return (
+        <>
+        <span>showFilteredOnly</span>
+        <Switch
+            checked={showFilteredOnly}
+            onChange={this.onChange}
+            size="small"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            filterTreeNode
+            showFilteredOnly={showFilteredOnly}
+            placeholder="单选可搜索的"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            filterTreeNode
+            maxTagCount={2}
+            showFilteredOnly={showFilteredOnly}
+            placeholder="多选可搜索的"
+            searchPlaceholder="请输入关键字开始搜索"
+        />
+        <br/>
+        <br/>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            filterTreeNode
+            maxTagCount={2}
+            showFilteredOnly={showFilteredOnly}
+            placeholder="搜索框autofocus"
+            searchPlaceholder="autofocus"
+            searchAutoFocus
+        />
+        </>
+    )
+    }
+}
+```
+
+### 搜索框位置
+
+可以使用 `searchPosition` 来设置搜索框的位置,可选: `dropdown`(默认)、`trigger`。
+
+当输入框位于 trigger 时: 
+1. 搜索框占位符由 `placeholder` 控制;
+2. `showClear=true` 时,点击输入框的清空按钮,将同时清空 inputValue 和 value。
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+    const treeData = [
+        {
+            label: 'Asia',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: 'China',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: 'Beijing',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: 'Shanghai',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+                {
+                    label: 'Japan',
+                    value: 'Japan',
+                    key: '0-1',
+                    children: [
+                        {
+                            label: 'Osaka',
+                            value: 'Osaka',
+                            key: '0-1-0'
+                        }
+                    ]
+                },
+            ],
+        },
+        {
+            label: 'North America',
+            value: 'North America',
+            key: '1',
+            children: [
+                {
+                    label: 'United States',
+                    value: 'United States',
+                    key: '1-0'
+                },
+                {
+                    label: 'Canada',
+                    value: 'Canada',
+                    key: '1-1'
+                }
+            ]
+        }
+    ];
+    return (
+        <>
+            <TreeSelect
+                searchPosition="trigger"
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                filterTreeNode
+                placeholder="单选"
+            />
+            <br />
+            <br />
+            <TreeSelect
+                searchPosition="trigger"
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                multiple
+                filterTreeNode
+                maxTagCount={2}
+                placeholder="多选"
+            />
+        </>
+    );
+}
+```
+
+### 尺寸大小
+
+可以通过 `size` 设置尺寸大小,可选: 'small'、'default'、'large'
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '亚洲',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: '中国',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: '北京',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: '上海',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+        ],
+    },
+    {
+        label: '北美洲',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return ( 
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="small"
+            placeholder="small"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="default"
+            placeholder="default"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            size="large"
+            placeholder="large"
+        />
+    </div>
+  )
+}
+```
+
+### 默认展开
+
+`defaultExpandAll` 和 `expandAll` 均可以设置 `TreeSelect` 的默认展开/收起状态。二者的区别是,`defaultExpandAll` 只在初始化时生效,而 `expandAll` 不仅会在初始化时生效,当数据(`treeData`)发生动态更新时,`expandAll` 也仍然生效。
+
+其中,`expandAll` 是从 1.30.0 开始支持的。
+
+在下面的 demo 中,`TreeData` 更新后,`defaultExpandAll` 失效,`expandAll` 仍然生效。
+
+```jsx live=true
+import React, { useEffect, useState } from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+() => {
+    const treeData = [
+        {
+            label: '亚洲',
+            value: 'Asia',
+            key: '0',
+            children: [
+                {
+                    label: '中国',
+                    value: 'China',
+                    key: '0-0',
+                    children: [
+                        {
+                            label: '北京',
+                            value: 'Beijing',
+                            key: '0-0-0',
+                        },
+                        {
+                            label: '上海',
+                            value: 'Shanghai',
+                            key: '0-0-1',
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            label: '北美洲',
+            value: 'North America',
+            key: '1',
+        }
+    ];
+
+    const [data, setData] = useState([]);
+
+    useEffect(() => {
+        setTimeout(() => setData(treeData), 500)
+    }, []);
+
+    return (
+        <>
+            <TreeSelect
+                style={{ width: 300, marginBottom: 20 }}
+                expandAll
+                treeData={data}
+                placeholder="expandAll"
+            />
+            <TreeSelect
+                style={{ width: 300 }}
+                defaultExpandAll
+                treeData={data}
+                placeholder="defaultExpandAll"
+            />
+        </>
+    )
+}
+
+```
+
+### 禁用
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+() => {
+  const treeData = [
+    {
+        label: '亚洲',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: '中国',
+                value: 'China',
+                key: '0-0',
+                children: [
+                    {
+                        label: '北京',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: '上海',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+        ],
+    },
+    {
+        label: '北美洲',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return ( 
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disabled
+            placeholder="禁用下拉菜单"
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            defaultValue={'Shanghai'}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disabled
+        />
+        <br />
+        <br />
+        <TreeSelect
+            style={{ width: 300 }}
+            defaultValue={['Shanghai', 'North America']}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            multiple
+            disabled
+        />
+    </div>
+  )
+}
+```
+
+### 严格禁用
+
+version: >= 1.30.0
+
+可以使用 `disableStrictly` 来开启严格禁用。开启严格禁用后,当节点是 disabled 的时候,则不能通过子级或者父级的关系改变选中状态。
+
+以下面的 demo 为例,节点"中国"开启了严格禁用,因此,当我们改变其父节点"亚洲"的选中状态时,也不会影响到节点"中国"的选中状态。
+
+```jsx live=true
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+  const treeData = [
+    {
+        label: '亚洲',
+        value: 'Asia',
+        key: '0',
+        children: [
+            {
+                label: '中国',
+                value: 'China',
+                key: '0-0',
+                disabled: true,
+                children: [
+                    {
+                        label: '北京',
+                        value: 'Beijing',
+                        key: '0-0-0',
+                    },
+                    {
+                        label: '上海',
+                        value: 'Shanghai',
+                        key: '0-0-1',
+                    },
+                ],
+            },
+            {
+                label: '日本',
+                value: 'Japan',
+                key: '0-1',
+            },
+        ],
+    },
+    {
+        label: '北美洲',
+        value: 'North America',
+        key: '1',
+    }
+  ]
+  return ( 
+    <div>
+        <TreeSelect
+            style={{ width: 300 }}
+            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+            treeData={treeData}
+            disableStrictly
+            multiple
+            defaultValue={['Shanghai']}
+        />
+    </div>
+  )
+}
+
+```
+
+### 受控
+传入 `value` 时即为受控组件,可以配合 `onChange` 使用。
+```jsx live=true hideInDSM
+import React from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            value: 'Shanghai'
+        };
+    }
+    onChange(value) {
+        this.setState({value})
+    }
+    render() {
+        const treeData = [
+            {
+                label: '亚洲',
+                value: 'Asia',
+                key: '0',
+                children: [
+                    {
+                        label: '中国',
+                        value: 'China',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: '北京',
+                                value: 'Beijing',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: '上海',
+                                value: 'Shanghai',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: '北美洲',
+                value: 'North America',
+                key: '1',
+            }
+        ];
+        return (
+            <TreeSelect
+                style={{ width: 300 }}
+                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                treeData={treeData}
+                value={this.state.value}
+                placeholder="请选择"
+                onChange={e => this.onChange(e)}
+            />
+        )
+    }
+}
+```
+
+### 虚拟化
+列表虚拟化,用于大量树节点的情况。开启后,动画效果将被关闭。
+
+`virtualize` 是一个包含下列值的对象: 
+- height: 高度值,如果为 string 必须有计算高度才能被渲染出来,即其父节点有 offsetHeight。建议传入数组。
+- width: 宽度值,默认 100%
+- itemSize: 每行的treeNode的高度,必传
+
+如果带搜索框,建议开启 `showFilteredOnly` 减少多余节点的渲染。
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+class Demo extends React.Component {
+    constructor() {
+        super();
+        this.state = {
+            gData: [],
+            total: 0,
+        }
+        this.onGen = this.onGen.bind(this);
+    }
+
+    generateData(x = 5, y = 4, z = 3, gData = []) {
+        // x:每一级下的节点总数。y:每级节点里有y个节点、存在子节点。z:树的level层级数(0表示一级)
+        function _loop(_level, _preKey, _tns) {
+            const preKey = _preKey || '0';
+            const tns = _tns || gData;
+
+            const children = [];
+            for (let i = 0; i < x; i++) {
+                const key = `${preKey}-${i}`;
+                tns.push({ label: `${key}-标签`, key: `${key}-key`, value: `${key}-value` });
+                if (i < y) {
+                    children.push(key);
+                }
+            }
+            if (_level < 0) {
+                return tns;
+            }
+            const __level = _level - 1;
+            children.forEach((key, index) => {
+                tns[index].children = [];
+                return _loop(__level, key, tns[index].children);
+            });
+
+            return null;
+        }
+        _loop(z);
+        
+        function calcTotal(x, y, z) {
+            const rec = n => (n >= 0 ? x * y ** n-- + rec(n) : 0);
+            return rec(z + 1);
+        }
+        return {gData, total: calcTotal(x, y, z)};
+    }
+
+      
+    onGen() {
+        const { gData, total } = this.generateData();
+        this.setState({
+            gData,
+            total
+        });
+    };
+  
+    render() {
+        const style = {
+            width: 260,
+            height: 360,
+            border: '1px solid var(--semi-color-border)'
+        }
+      return (
+        <div style={{ padding: '0 20px' }}>
+          <Button onClick={this.onGen}>生成数据: </Button>
+          <span>共 {this.state.total} 个节点</span>
+          <br/>
+          <br/>
+          {this.state.gData.length ? (
+                <TreeSelect
+                  style={{ width: 300 }}
+                  treeData={this.state.gData}
+                  filterTreeNode
+                  showFilteredOnly
+                  placeholder="Please select"
+                  dropdownStyle={{ 
+                      // height: 300,
+                      overflow: 'hidden'
+                    }}
+                  virtualize={{
+                    itemSize: 28,
+                    // dropDown height 300 minus search box height minus padding 8 * 2
+                    // or if you set dropdown height, it will fill 100% of rest space
+                    height: 236                
+                  }}
+            />
+          ) : null}
+        </div>
+      );
+    }
+}
+```
+
+### 动态更新数据
+```jsx live=true hideInDSM
+import React from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+class Demo extends React.Component {
+    constructor() {
+        super()
+        this.state = {
+            treeData: [],
+        }
+        this.add = this.add.bind(this);
+    }
+    add() {
+        let itemLength = Math.floor(Math.random() * 5) + 1;
+        let treeData = new Array(itemLength).fill(0).map((v, i) => {
+            let length = Math.floor(Math.random() * 3);
+            let children = new Array(length).fill(0).map((cv, ci) => {
+                let child = {
+                    key: `${i}-${ci}`,
+                    label: `Leaf-${i}-${ci}`,
+                    value: `${i}-${ci}`
+                }
+                return child;
+            });
+            let item = {
+                key: `${i}`,
+                label: `Item-${i}`,
+                value: `${i}`,
+                children
+            };
+            return item;
+        })
+        this.setState({ treeData });
+    }
+    render() {
+        return (
+            <>
+                <TreeSelect
+                    style={{ width: 300 }}
+                    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+                    treeData={this.state.treeData}
+                    placeholder="请选择"
+                />
+                <br/>
+                <br/>
+                <Button onClick={this.add}>
+                    动态改变数据
+                </Button>
+            </>
+        )
+    }
+}
+```
+
+### 异步加载数据
+通过设置 `loadData` 可以动态加载数据,此时需要在数据中传入 `isLeaf` 标明叶子节点。
+
+```jsx live=true hideInDSM
+import React, { useState } from 'react';
+import { TreeSelect } from '@douyinfe/semi-ui';
+
+() => {
+    const initialData = [
+        {
+            label: 'Expand to load',
+            value: '0',
+            key: '0',
+        },
+        {
+            label: 'Expand to load',
+            value: '1',
+            key: '1',
+        },
+        {
+            label: 'Leaf Node',
+            value: '2',
+            key: '2',
+            isLeaf: true,
+        },
+    ];
+    const [treeData, setTreeData] = useState(initialData);
+
+    function updateTreeData(list, key, children) {
+        return list.map(node => {
+            if (node.key === key) {
+                return { ...node, children };
+            }
+            if (node.children) {
+                return { ...node, children: updateTreeData(node.children, key, children) };
+            }
+            return node;
+        });
+    }
+
+    function onLoadData({ key, children }) {
+        return new Promise(resolve => {
+            if (children) {
+                resolve();
+                return;
+            }
+            setTimeout(() => {
+                setTreeData(origin =>
+                    updateTreeData(origin, key, [
+                        {
+                            label: 'Child Node',
+                            key: `${key}-0`,
+                        },
+                        {
+                            label: 'Child Node',
+                            key: `${key}-1`,
+                        },
+                    ]),
+                );
+                resolve();
+            }, 1000);
+        });
+    }
+    return (
+        <TreeSelect
+            loadData={onLoadData}
+            treeData={treeData}
+            style={{ width: 300 }}
+            placeholder="请选择"
+        />
+    );
+};
+```
+
+### 自定义 Trigger
+
+如果默认的触发器样式满足不了你的需求,可以用 `triggerRender` 自定义选择框的展示。
+
+triggerRender 入参如下:
+
+```typescript
+interface triggerRenderProps {
+    componentProps: TreeSelectProps;// 所有用户传给 TreeSelect 的 props
+    disabled: boolean;              // 是否禁用 TreeSelect
+    value: TreeNode[];              // 已选中的 node 的数据
+    inputValue: string;             // 当前 input 框的输入值
+    onClear: e => void;             // 用于清空值的函数
+    placeholder: string;            // placeholder
+}
+```
+
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { TreeSelect, Button } from '@douyinfe/semi-ui';
+import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+            {
+                label: '亚洲',
+                value: '亚洲',
+                key: '0',
+                children: [
+                    {
+                        label: '中国',
+                        value: '中国',
+                        key: '0-0',
+                        children: [
+                            {
+                                label: '北京',
+                                value: '北京',
+                                key: '0-0-0',
+                            },
+                            {
+                                label: '上海',
+                                value: '上海',
+                                key: '0-0-1',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                label: '北美洲',
+                value: '北美洲',
+                key: '1',
+            }
+        ], []);
+    const onChange = useCallback((val) => {
+        setValue(val);
+    }, []);
+    const onClear = useCallback(e => {
+        e && e.stopPropagation();
+        setValue([]);
+    }, []);
+
+    const closeIcon = useMemo(() => {
+        return value && value.length ? <IconClose onClick={onClear} /> : <IconChevronDown />;
+    }, [value]);
+
+    return (
+        <TreeSelect
+            onChange={onChange}
+            style={{ width: 300 }}
+            value={value}
+            multiple
+            treeData={treeData}
+            placeholder='Custom Trigger'
+            triggerRender={({ placeholder }) => (
+                <Button theme={'light'} icon={closeIcon} iconPosition={'right'}>
+                    {value && value.length ? value.join(',') : placeholder}
+                </Button>
+            )}
+        />
+    );
+}
+```
+
+### 自定义渲染已选项
+
+你可以通过 renderSelectedItem 自定义选择框中已选项标签的渲染结构。
+
+- 单选时 `renderSelectedItem(treeNode: TreeNode) => content:ReactNode`
+- 多选时 `renderSelectedItem(treeNode: TreeNode, { index:number, onClose:function }) => { isRenderInTag:bool, content:ReactNode }`
+    - isRenderInTag 为 true 时,会自动将 content 包裹在 Tag 中渲染(带有背景色以及关闭按钮)
+    - isRenderInTag 为 false 时,将直接渲染返回的 content
+
+```jsx live=true
+import React, { useState, useCallback, useMemo } from 'react';
+import { TreeSelect, Tag } from '@douyinfe/semi-ui';
+
+function Demo() {
+    const [value, setValue] = useState([]);
+    const treeData = useMemo(() => [
+      {
+          label: '亚洲',
+          value: 'Asia',
+          key: '0',
+          children: [
+              {
+                  label: '中国',
+                  value: 'China',
+                  key: '0-0',
+                  children: [
+                      {
+                          label: '北京',
+                          value: 'Beijing',
+                          key: '0-0-0',
+                      },
+                      {
+                          label: '上海',
+                          value: 'Shanghai',
+                          key: '0-0-1',
+                      },
+                  ],
+              },
+          ],
+      },
+      {
+        label: '北美洲',
+        value: 'North America',
+        key: '1',
+      },
+      {
+        label: '南美洲',
+        value: 'South America',
+        key: '2',
+      },
+      {
+        label: '南极洲',
+        value: 'Antarctica',
+        key: '3',
+      },
+    ], []);
+    
+    return (
+        <>
+            <h4>单选</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                renderSelectedItem={item => item.label}
+            />
+            <h4>多选+ isRenderInTag=true</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                multiple
+                renderSelectedItem={(item, { index, onClose }) => ({ content: item.label, isRenderInTag: true })}
+            />
+            <h4>多选 + isRenderInTag=false</h4>
+            <TreeSelect
+                style={{ width: 300 }}
+                treeData={treeData}
+                multiple
+                maxTagCount={2}
+                renderSelectedItem={(item, { index, onClose }) => {
+                    return  ({ 
+                        content: (
+                            <Tag 
+                                key={index} 
+                                color="white" 
+                                closable 
+                                onClose={onClose}
+                            >
+                                {item.value}
+                            </Tag>
+                        ), 
+                        isRenderInTag: false
+                    });
+                }}
+            />
+        </>
+    );
+}
+```
+
+## API参考
+
+### TreeSelect
+
+| 属性            | 说明         | 类型           | 默认值          |  版本  |
+|-------------   | ----------- | -------------- | -------------- |-------- |
+| arrowIcon|自定义右侧下拉箭头Icon,当showClear开关打开且当前有选中值时,hover会优先显示clear icon| ReactNode | | 1.15.0|
+| autoAdjustOverflow|浮层被遮挡时是否自动调整方向(暂时仅支持竖直方向,且插入的父级为 body)|boolean | true| 0.34.0|
+| autoExpandParent | 是否自动展开父节点 | boolean | false | 0.34.0 |
+| className | 选择框的 `className` 属性 | string | - | - |
+| clickToHide  | 选择后是否自动关闭下拉弹层,仅单选模式有效  | boolean    | true | 1.5.0      |
+| defaultExpandAll | 设置在初始化时是否展开所有节点。而如果后续数据(`treeData`)发生改变,这个 api 是无法影响节点的展开情况的,如果有这个需要可以使用 `expandAll` | boolean | false | 0.32.0 |
+| defaultExpandedKeys | 默认展开的节点,显示其直接子级 | string\[] | - | 0.32.0 |
+| defaultOpen | 默认展开下拉菜单 | boolean | false | 0.32.0 |
+| defaultValue | 指定默认选中的条目 | string \| number \| TreeNode \| (string \| number \| TreeNode)[] | - | - |
+| disabled | 是否禁用 | boolean | false | - |
+| disableStrictly | 是否严格禁用 | boolean | false | 1.30.0 |
+| dropdownClassName | 下拉菜单的 `className` 属性 | string | - | - |
+| dropdownMatchSelectWidth | 下拉菜单最小宽度是否等于Select |    boolean        | true | - |
+| dropdownStyle | 下拉菜单的样式 | CSSProperties | - | - |
+| emptyContent | 当搜索无结果时展示的内容 | ReactNode | `暂无数据` | - |
+| expandAction             | 展开逻辑,可选 false, 'click', 'doubleClick'。默认值为 false,即仅当点击展开按钮时才会展开  | boolean \| string   | false | 1.4.0      |
+| expandAll | 设置是否默认展开所有节点,若后续数据(`treeData`)发生改变,默认的展开情况也是会受到这个 api 影响的 | boolean | false | 1.30.0 |
+| expandedKeys | (受控)展开的节点,默认展开节点显示其直接子级 | string[] | - | 0.32.0 |
+| filterTreeNode | 是否根据输入项进行筛选,默认用 `treeNodeFilterProp` 的值作为要筛选的 `TreeNode` 的属性值 | boolean\|(inputValue: string, treeNodeString: string) => boolean | false | - |
+| getPopupContainer  | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 `position: relative`     | function():HTMLElement | - | - |
+| insetLabel | 前缀标签别名,主要用于 Form | ReactNode | - |0.28.0 |
+| labelEllipsis | 是否开启label的超出省略,默认虚拟化状态下开启 | boolean | false\|true(virtualized) | 1.8.0 | 
+| leafOnly | 多选模式下是否开启 onChange 回调入参及展示标签只有叶子节点 | boolean | false |0.32.0 |
+| loadData | 异步加载数据,需要返回一个Promise | (treeNode: TreeNode) => Promise |- |  1.32.0|
+| loadedKeys | (受控)已经加载的节点,配合 loadData 使用 | Set< string > | - | 1.32.0|
+| maxTagCount | 最多显示多少个 tag | number | - | - |
+| motionExpand | 是否开启选项树节点动画 | boolean | true | - |
+| multiple | 是否支持多选 | boolean | false | - |
+| optionListStyle | optionList的样式 | CSSProperties | - | 1.8.0 |
+| outerBottomSlot          | 渲染在弹出层底部,与 optionList 平级的自定义 slot   | ReactNode  |  - | 1.1.0|
+| outerTopSlot| 渲染在弹出层顶部,与 optionList 平级的自定义 slot,注意如果开启了 filterTreeNode 会取代搜索框,可以通过 search 方法来自行处理 |  ReactNode  |  - | 1.9.0|
+| placeholder | 选择框默认文字 | string | - | - |
+| prefix | 前缀标签 | ReactNode | - |0.28.0 |
+| renderFullLabel | 完全自定义label的渲染函数,[入参及用法详见](/zh-CN/navigation/tree#高级定制) | (obj) => ReactNode | - | 1.7.0 | 
+| renderLabel | 自定义label的渲染函数,[入参及用法详见](/zh-CN/navigation/tree#自定义节点内容)  | (label:ReactNode, data:TreeNode) => ReactNode | - | 1.6.0 | 
+| renderSelectedItem | 自定义渲染已选项 | Function | - | 1.26.0 | 
+| searchAutoFocus | 搜索框自动聚焦 | boolean | false | 1.27.0 |
+| searchPlaceholder | 搜索框默认文字 | string | - | - |
+| searchPosition | 设置搜索框的位置,可选: `dropdown`、`trigger` | string | `dropdown` | 1.29.0 |
+| showClear | 当值不为空时,trigger 是否展示清除按钮  | boolean | false |  |
+| showFilteredOnly | 搜索状态下是否只展示过滤后的结果 | boolean | false | 0.32.0 |
+| showSearchClear | 是否显示搜索框的清除按钮 | boolean | true | 0.35.0 |
+| size | 选择框大小,可选 `large`,`small`,`default` | string | `default` | - |
+| style | 选择框的样式  | CSSProperties | - | - |
+| suffix | 后缀标签 | ReactNode | - |0.28.0|
+| treeData | `treeNodes` 数据,如果设置则不需要手动构造 `TreeNode` 节点(`key` 值在整个树范围内唯一) | TreeNode[] | \[] | - |
+| treeNodeFilterProp | 搜索时输入项过滤对应的 `treeNode` 属性 | string | `label` | - |
+| treeNodeLabelProp | 作为显示的 `prop` 设置 | string | `label` | - |
+| triggerRender | 自定义触发器渲染方法  | ({ placeholder: string }) => ReactNode | - | 0.34.0 |
+| validateStatus | 校验结果,可选 `warning`、`error`、 `default`(只影响样式背景色) | string | - | 0.32.0 |
+| value | 当前选中的节点的value值,传入该值时将作为受控组件 | string \| number \| TreeNode \| (string \| number \| TreeNode)[] | - | - |
+| virtualize | 列表虚拟化,用于大量树节点的情况,由 height, width, itemSize 组成,参考 Tree - Virtualize Object。开启后将关闭动画效果。 | object | - | 0.32.0 |
+| zIndex | treeSelect下拉菜单的zIndex | number | 1030 | 0.30.0 |
+| onBlur | 失去焦点时的回调 | function(event) | - | - |
+| onChange | 选中树节点时调用此函数,默认返回值为当前所有选中项的value值及节点属性;如果是通过tag关闭,event参数为null | Function | - | - |
+| onChangeWithObject | 是否将选中项 option 的其他属性作为回调。设为 true 时,onChange 的入参类型Function(node\|node[], e) 此时如果是受控,也需要把 value 设置成 object,且必须含有 value 的键值;defaultValue同理。 | boolean | false | 1.0.0 |
+| onExpand | 展示节点时调用 | function(expandedKeys:array, {expanded: bool, node}) | - | - |
+| onFocus | 聚焦时的回调 | function(event) | - | - |
+| onLoad | 节点加载完毕时触发的回调 | (loadedKeys: Set< string >, treeNode: TreeNode) => void |- |  1.32.0|
+| onSearch | 文本框值变化时回调 | function(sugInput: string) | - | - |
+| onSelect | 被选中时调用,返回值为当前事件选项的key值 | function(selectedKey:string, selected: bool, selectedNode: TreeNode) | - | - |
+| onVisibleChange     | 弹出层展示/隐藏时触发的回调   | function(isVisble:boolean) |     |   1.4.0  |
+
+### TreeNode
+
+> __不同 `TreeNode` 的 key 值要求必填且唯一。__`label` 允许重复。**v>=1.7.0** 之前 value 值要求必须必填且唯一。
+> **v>=1.7.0** 之后 value 值非必填。此时 onChange, value, defaultValue 及 onChangeWithObject 中所取的 value 属性值将改为 key 值。
+> 为了保证行为的符合预期,treeData 中的 value 值或者全部不填写,或者全部填写且唯一,不建议混写。
+
+| 属性            | 说明         | 类型           | 默认值          |
+|-------------   | ----------- | -------------- | -------------- |
+| value | 属性值 | string\|number | - |
+| label | 展示的文本 | string\|ReactNode | - |
+| icon | 自定义图标 | ReactNode | - |
+| disabled | 是否禁用,多选状态下支持 | boolean | false |
+| key | required且要求唯一 | string | - |
+| isLeaf| 是否为叶子节点 | boolean |-|
+
+## 设计变量
+<DesignToken/>
+
+### Method
+- search(sugInput: string)
+如果需要自定义搜索框可以使用该方法。

+ 1159 - 0
content/input/upload/index-en-US.md

@@ -0,0 +1,1159 @@
+---
+localeCode: en-US
+order: 32
+category: Input
+title: Upload
+icon: doc-upload
+width: 50%
+brief: File selection upload
+---
+
+## Demos
+
+### How to import
+
+```jsx import
+import { Upload } from '@douyinfe/semi-ui';
+```
+### Basic usage
+
+The most basic usage is to place a Button in children, click on the children content (the placed Button) to activate the file selection box, and the upload will start automatically after the selection is completed
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+<Upload action="//semi.design/api/upload">
+    <Button icon={<IconUpload />} theme="light">
+        Click upload
+    </Button>
+</Upload>
+```
+
+### Add prompt text
+
+Set a custom prompt text through the `prompt` slot
+Set the slot position by `promptPosition`, optional `left`, `right`, `bottom`, the default is `right`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const action = '//semi.design/api/upload';
+    const getPrompt = (pos, isListType) => {
+        let basicStyle = { display: 'flex', alignItems: 'center', color: 'grey', height: isListType ? '100%' : 32 };
+        let marginStyle = {
+            left: { marginRight: 10 },
+            right: { marginLeft: 10 },
+        };
+        let style = { ...basicStyle, ...marginStyle[pos] };
+
+        return <div style={style}>Please upload qualification certification materials</div>;
+    };
+    const button = (
+        <Button icon={<IconUpload />} theme="light">
+            Click upload
+        </Button>
+    );
+    const positions = ['right', 'left', 'bottom'];
+    return (
+        <>
+            {positions.map((pos, index) => (
+                <>
+                    {index ? (
+                        <div
+                            style={{ marginBottom: 12, marginTop: 12, borderBottom: '1px solid var(--semi-color-border)' }}
+                        ></div>
+                    ) : null}
+                    <Upload action={action} prompt={getPrompt(pos)} promptPosition={pos}>
+                        {button}
+                    </Upload>
+                </>
+            ))}
+        </>
+    );
+};
+```
+
+When listType is picture, the reference object at promptPosition is the whole picture wall list
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    const action = '//semi.design/api/upload';
+    const getPrompt = (pos, isListType) => {
+        let basicStyle = { display: 'flex', alignItems: 'center', color: 'grey', height: isListType ? '100%' : 32 };
+        let marginStyle = {
+            left: { marginRight: 10 },
+            right: { marginLeft: 10 },
+        };
+        let style = { ...basicStyle, ...marginStyle[pos] };
+
+        return <div style={style}>Please upload pet certification materials</div>;
+    };
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'jiafang1.jpeg',
+            status: 'success',
+            size: '130kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
+        },
+        {
+            uid: '2',
+            name: 'jiafang2.jpeg',
+            size: '222kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
+        },
+        {
+            uid: '5',
+            name: 'jiafang3.jpeg',
+            percent: 50,
+            size: '222kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg',
+        },
+    ];
+    const positions = ['right', 'bottom'];
+    return (
+        <>
+            {positions.map((pos, index) => (
+                <>
+                    {index ? (
+                        <div
+                            style={{ marginBottom: 12, marginTop: 12, borderBottom: '1px solid var(--semi-color-border)' }}
+                        ></div>
+                    ) : null}
+                    <Upload
+                        action={action}
+                        prompt={getPrompt(pos, true)}
+                        promptPosition={pos}
+                        listType="picture"
+                        defaultFileList={defaultFileList}
+                    >
+                        <IconPlus size="extra-large" />
+                    </Upload>
+                </>
+            ))}
+        </>
+    );
+};
+```
+
+### Click on the avatar to trigger upload
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Avatar, Toast } from '@douyinfe/semi-ui';
+import { IconCamera } from '@douyinfe/semi-icons';
+
+() => {
+    const [url, setUrl] = useState('https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg');
+    const onSuccess = (response, file) => {
+        Toast.success('Avatar updated successfully');
+        // const url = response.url;
+        setUrl('https://sf6-cdn-tos.douyinstatic.com/obj/ttfe/ies/semi/ttmoment.jpeg');
+    };
+
+    const style = {
+        backgroundColor: 'rgba(0,0,0,.4)',
+        height: '100%',
+        width: '100%',
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'center',
+        color: '#FFF',
+    };
+    
+    const hoverMask =  (<div style={style}>
+        <IconCamera />
+    </div>);
+
+    const api = '//semi.design/api/upload';
+    let imageOnly = 'image/*';
+
+    return (
+        <Upload
+            className="avatar-upload"
+            action={api}
+            onSuccess={onSuccess}
+            accept={imageOnly}
+            showUploadList={false}
+            onError={() => Toast.error('upload failed')}
+        >
+            <Avatar src={url} style={{ margin: 4 }} hoverMask={hoverMask} />
+        </Upload>
+    )
+}
+```
+
+```css
+.avatar-upload .semi-upload-add {
+    border-radius: 50%; // Make sure that only the circle is clicked on the hot zone
+}
+```
+
+### Custom upload attributes
+
+Custom upload attributes can be added by setting `data`, `headers`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    let data = {
+        role: 'ies',
+        time: new Date().getTime(),
+    };
+    let headers = {
+        'x-tt-semi': 'semi-upload',
+    };
+    return (
+        <Upload action={action} data={data} headers={headers}>
+            <Button icon={<IconUpload />} theme="light">
+                Click upload
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### Upload file type
+
+The type of files uploaded can be restricted through the `accept` attribute (the native `html` attribute of `input`).
+
+`accept` supports the following two types of strings:
+
+- A collection of file extensions (recommended), such as .jpg, .png, etc.;
+- MIME types collection of file types, please refer to [MDN document](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types)
+
+For example, only allowing users to upload PNG and PDF files, `accept` can be written like this: `accept ='.pdf,.png'` or `accept ='application/pdf,image/png'` (the MIME type of PNG and PDF Connect through `,`).
+
+<Notice type="primary" title="Notes">
+     <div>Upload will intercept files that do not meet the accept format internally. When files that do not meet the format requirements are intercepted, the onAcceptInvalid method (provided by v1.24) will be triggered;</div>
+     <div>accept uses the suffix to avoid the incompatibility between file.type and MIME due to different browsers or operating systems. </div>
+</Notice>
+
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    let imageOnly = 'image/*';
+    let videoOnly = 'video/*';
+    let fileLimit = '.pdf,.png,.jpeg';
+    return (
+        <>
+            <Upload action={action} accept={imageOnly} style={{ marginBottom: 12 }}>
+                <Button icon={<IconUpload />} theme="light">
+                    Upload image
+                </Button>
+            </Upload>
+            <Upload action={action} accept={videoOnly} style={{ marginBottom: 12 }}>
+                <Button icon={<IconUpload />} theme="light">
+                    Upload video
+                </Button>
+            </Upload>
+            <Upload action={action} accept={fileLimit}>
+                <Button icon={<IconUpload />} theme="light">
+                    Upload PDF, PNG, JPEG
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### Upload folder
+
+By passing in `directory` as `true`, all files in the folder can be uploaded
+
+```jsx live=true
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    return (
+        <>
+            <Upload action={action} directory>
+                <Button icon={<IconUpload />} theme="light">
+                    Upload folder
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### Select multiple files at once
+
+You can select multiple files to upload at the same time by setting the `multiple` attribute.
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    return (
+        <Upload action={action} multiple>
+            <Button icon={<IconUpload />} theme="light">
+                Click upload
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### Limit the total number of files
+
+You can limit the maximum number of files that can be uploaded by setting the `limit` property
+When `limit` is 1, always replace the current one with the latest upload, and will not trigger the onExceed callback **v1.5.0 takes effect**
+
+```jsx dir="column" live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://semi.design/api/upload';
+    let limit = 1;
+    let onChange = props => {
+        console.log(props.fileList)
+    };
+    return (
+        <Upload
+            action={action}
+            limit={limit}
+            onChange={onChange}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                Click to upload (up to {limit} items)
+            </Button>
+        </Upload>
+    );
+};
+```
+
+```jsx dir="column" live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://semi.design/api/upload';
+    let [disabled, setDisabled] = useState(false);
+    let limit = 2;
+    let onChange = props => {
+        let length = props.fileList.length;
+        if (length === limit) {
+            setDisabled(true);
+        } else {
+            setDisabled(false);
+        }
+    };
+    return (
+        <Upload
+            action={action}
+            limit={limit}
+            onExceed={() => Toast.warning(`Up to ${limit} files are allowed to be uploaded`)}
+            onChange={onChange}
+        >
+            <Button icon={<IconUpload />} theme="light" disabled={disabled}>
+                Click to upload (up to {limit} items)
+            </Button>
+        </Upload>
+    );
+};
+```
+
+In the photo wall mode, when the number of uploaded files is equal to the limit, the upload entry will be automatically hidden
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'success',
+            size: '222KB',
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'tiktok.jpeg', { type: 'image/png' }),
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/a0ca113c9c6d4fb49c9b8bb54a392a00~noop.image',
+        },
+    ];
+    return (
+        <Upload
+            action={action}
+            limit={2}
+            listType="picture"
+            accept="image/*"
+            defaultFileList={defaultFileList}
+            onExceed={() => Toast.warning('Only allow up to 2 files to be uploaded')}
+        >
+            <IconPlus size="extra-large" />
+        </Upload>
+    );
+};
+```
+
+### Limit upload file size
+
+The upload file size limit can be customized through the `maxSize` and `minSize` properties, and the callback when the limit is exceeded can be set by setting `onSizeError`.
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+
+    return (
+        <>
+            <Upload
+                action={action}
+                maxSize={1024}
+                minSize={200}
+                onSizeError={(file, fileList) => Toast.error(`${file.name} size invalid`)}
+            >
+                <Button icon={<IconUpload />} theme="light">
+                    Click to upload (minimum 200KB, maximum 1MB)
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### Custom preview logic
+
+When `listType` is `list`, you can pass in `previewFile` to view the logic.
+For example, when you do not need to preview the image type by thumbnail, you can always return a `<IconFile />` in `previewFile`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload, IconFile } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+    ];
+    return (
+        <Upload
+            defaultFileList={defaultFileList}
+            action={action}
+            previewFile={file => <IconFile size="large" />}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                Click upload
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### Default file list
+
+The uploaded files can be displayed through `defaultFileList`. When you need to preview the thumbnail of the default file, you can set the `preview` attribute of the corresponding `item` in `defaultFileList` to `true`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'uploadFail',
+            size: '222KB',
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'tiktok.jpeg', { type: 'image/png' }),
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/a0ca113c9c6d4fb49c9b8bb54a392a00~noop.image',
+        },
+    ];
+
+    return (
+        <>
+            <Upload action={action} defaultFileList={defaultFileList}>
+                <Button icon={<IconUpload />} theme="light">
+                    Click upload
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### Controlled component
+
+When `fileList` is passed in, it is used as a controlled component. Need to listen to the onChange callback, and pass the fileList back to Upload (note that a new array object needs to be passed in)
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const initList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'validateFail',
+            size: '222KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg',
+        },
+        {
+            uid: '3',
+            name: 'jiafang.jpeg',
+            status: 'uploading',
+            size: '222KB',
+            percent: 50,
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'jiafang.jpeg', { type: 'image/jpeg' }),
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/4a55704fb0b8b85eaccdb4ed22469f57.jpg',
+        },
+    ];
+
+    const [list, updateList] = useState(initList);
+
+    const onChange = ({ fileList, currentFile, event }) => {
+        console.log('onChange');
+        console.log(fileList);
+        console.log(currentFile);
+        let newFileList = [...fileList]; // spread to get new array
+        updateList(newFileList);
+    }
+
+    return (
+        <Upload
+            action="//semi.design/api/upload"
+            onChange={onChange}
+            fileList={list}
+            showRetry={false}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                Click upload
+            </Button>
+        </Upload>
+    )
+}
+```
+
+### Photo Wall
+
+Set `listType ='picture'`, users can upload pictures and display thumbnails in the list
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    let action = '//semi.design/api/upload';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'jiafang.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+    ];
+    return (
+        <>
+            <Upload action={action} listType="picture" accept="image/*" multiple defaultFileList={defaultFileList}>
+                <IconPlus size="extra-large" />
+            </Upload>
+        </>
+    );
+};
+```
+
+### Disabled
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'validateFail',
+            size: '222KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
+        },
+    ];
+    let action = '//semi.design/api/upload';
+    return (
+        <>
+            <Upload action={action} disabled defaultFileList={defaultFileList}>
+                <Button icon={<IconUpload />} theme="light" disabled>
+                    Click upload
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### Manually trigger upload
+
+`uploadTrigger='custom'`, the upload will not be triggered automatically after the file is selected. Need to manually call the upload method on the ref to trigger
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload, IconPlus } from '@douyinfe/semi-icons';
+
+class ManulUploadDemo extends React.Component {
+    constructor() {
+        super();
+        this.manulUpload = this.manulUpload.bind(this);
+        this.uploadRef = React.createRef();
+    }
+
+    manulUpload() {
+        this.uploadRef.current.upload();
+    }
+
+    render() {
+        let action = '//semi.design/api/upload';
+        return (
+            <div>
+                <Upload
+                    accept="image/gif, image/png, image/jpeg, image/bmp, image/webp"
+                    action={action}
+                    uploadTrigger="custom"
+                    ref={this.uploadRef}
+                    onSuccess={(...v) => console.log(...v)}
+                    onError={(...v) => console.log(...v)}
+                >
+                    <Button icon={<IconPlus />} theme="light" style={{ marginRight: 8 }}>
+                        Select a document
+                    </Button>
+                    <Button icon={<IconUpload />} theme="light" onClick={this.manulUpload}>
+                        Start upload
+                    </Button>
+                </Upload>
+            </div>
+        );
+    }
+}
+```
+
+### Drag and drop upload
+
+`draggable='true'`, you can use the drag and drop function
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+
+() => (
+    <Upload
+        action="//semi.design/api/upload"
+        draggable={true}
+        dragMainText="Click to upload the file or drag and drop the file here"
+        dragSubText="Support any type of file"
+    ></Upload>
+);
+```
+
+You can quickly set the content of the drag area through `dragIcon`, `dragMainText`, `dragSubText`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconBolt } from '@douyinfe/semi-icons';
+
+() => <Upload
+    action="//semi.design/api/upload"
+    dragIcon={<IconBolt />}
+    draggable={true}
+    accept="application/pdf,.jpeg"
+    dragMainText={'Click to upload the file or drag and drop the file here'}
+    dragSubText="Only supports jpeg, pdf"
+    style={{ marginTop: 10 }}
+></Upload>
+```
+
+You can also pass in ReactNode through `children` to completely customize the display of the drag area
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconBolt } from '@douyinfe/semi-icons';
+
+() => (<Upload
+    action="//semi.design/api/upload"
+    dragIcon={<IconBolt />}
+    draggable={true}
+    accept="application/pdf,.jpeg"
+    style={{ marginTop: 10 }}
+>
+    <div className="components-upload-demo-drag-area">
+        <img
+            src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/0f2a32f27eab90a296814fbc26103b2b.jpg"
+            height="96"
+            style={{ borderRadius: 4 }}
+        />
+        <div
+            style={{
+                fontSize: 14,
+                marginTop: 8,
+                flexBasis: '100%',
+                textAlign: 'center',
+                color: 'var(--semi-color-tertiary)',
+            }}
+        >
+            Wow, you can really dance.
+        </div>
+    </div>
+    </Upload>
+)
+```
+
+The scss style is as follows
+
+```scss
+.components-upload-demo-drag-area {
+    border-radius: var(--semi-border-radius-small);
+    border: 2px dashed var(--semi-color-border);
+    width: 100%;
+    padding: 12px;
+    background-color: var(--semi-color-tertiary-light-default);
+    display: flex;
+    cursor: pointer;
+    flex-wrap: wrap;
+    justify-content: center;
+    &:hover {
+        background-color: var(--semi-color-primary-light-default);
+        border-color: var(--semi-color-primary);
+    }
+}
+```
+
+### Custom check before upload
+
+The file status can be updated through the `beforeUpload` hook, which is to verify the file after selecting the file before uploading online, `({ file: FileItem, fileList: Array<FileItem> }) => beforeUploadResult | Promise | boolean` During synchronization verification, a boolean (true means the verification passed, false means the verification failed, and the verification failure will prevent the file from uploading online) or an Object object. The specific structure is as follows
+
+```ts
+// beforeUploadResult:
+{
+     fileInstance?: File,
+     status?:'success' |'uploadFail' |'validateFail' |'validating' |'uploading' |'wait',
+     validateMessage?: React.ReactNode | string, // file validation information
+     shouldUpload: boolean, // Whether to upload. The default is true, if it is false, the fileItem will only be displayed in the list, and the upload operation will not be triggered
+     autoRemove: boolean, // Whether to remove the file from the fileList, the default is false
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class ValidateDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.beforeUpload = this.beforeUpload.bind(this);
+        this.transformFile = this.transformFile.bind(this);
+        this.count = 0;
+    }
+
+    transformFile(fileInstance) {
+        if (this.count === 0) {
+            let newFile = new File([fileInstance], 'newFileName', { type: 'image/png' });
+            return newFile;
+        } else {
+            return fileInstance;
+        }
+    }
+
+    beforeUpload({ file, fileList }) {
+        let result;
+        if (this.count > 0) {
+            result = {
+                autoRemove: false,
+                fileInstance: file.fileInstance,
+                shouldUpload: true,
+            };
+        } else {
+            result = {
+                autoRemove: false,
+                fileInstance: file.fileInstance,
+                status: 'validateFail',
+                shouldUpload: false,
+            };
+        }
+        this.count = this.count + 1;
+        return result;
+    }
+
+    render() {
+        return (
+            <Upload
+                action="//semi.design/api/upload"
+                transformFile={this.transformFile}
+                beforeUpload={this.beforeUpload}
+            >
+                <Button icon={<IconUpload />} theme="light">
+                    Click upload (synchronize check before upload)
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+In the case of asynchronous verification, a Promise must be returned. Promise reslove means that the verification is passed, and reject means that the verification fails and the upload will not be triggered.
+Object can be passed in when reslove/reject (the structure is the same as beforeUploadResult)
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class AsyncBeforeUploadDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.beforeUpload = this.beforeUpload.bind(this);
+        this.count = 0;
+    }
+
+    beforeUpload({ file, fileList }) {
+        let result;
+        return new Promise((reslove, reject) => {
+            if (this.count > 1) {
+                result = {
+                    autoRemove: false,
+                    shouldUpload: true,
+                };
+                this.count = this.count + 1;
+                reslove(result);
+            } else {
+                result = {
+                    autoRemove: false,
+                    fileInstance: file.fileInstance,
+                    status: 'validateFail',
+                    shouldUpload: false,
+                    validateMessage: `${this.count + 1} is doomed to fail`,
+                };
+                this.count = this.count + 1;
+                reject(result);
+            }
+        });
+    }
+
+    render() {
+        return (
+            <Upload action="//semi.design/api/upload" beforeUpload={this.beforeUpload}>
+                <Button icon={<IconUpload />} theme="light">
+                    Click upload (asynchronous verification before upload)
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+### Update file information after upload
+
+The file status, verification information, and file name can be updated through the `afterUpload` hook.
+`({ response: any, file: FileItem, fileList: Array<FileItem> }) => afterUploadResult`
+afterUpload is triggered when the upload is completed (xhr.onload) and no error occurs, it needs to return an Object object (asynchronous return is not supported), the specific structure is as follows
+
+```ts
+// afterUploadResult:
+{
+     status?:'success' |'uploadFail' |'validateFail' |'validating' |'uploading' |'wait',
+     validateMessage?: React.ReactNode | string, // file validation information
+     autoRemove: boolean, // Whether to remove the file from the fileList, the default is false
+     name: string,
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class ValidateDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.count = 0;
+    }
+
+    afterUpload({ response, file }) {
+        // It can be returned according to the business interface to determine whether the upload is successful.
+        if (response.status_code === 200) {
+            return {
+                autoRemove: false,
+                status: 'uploadFail',
+                validateMessage: 'The content is illegal',
+                name: 'RenameByServer.jpg',
+            };
+        } else {
+            return {};
+        }
+    }
+
+    render() {
+        return (
+            <Upload action="//semi.design/api/upload" afterUpload={this.afterUpload}>
+                <Button icon={<IconUpload />} theme="light">
+                    Click upload
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+### Custom request
+
+When customRequest is passed in, it is equivalent to using the custom request method to replace the upload built-in xhr request, and the user needs to take over the upload behavior by himself.
+The file object of the current operation can be obtained in the input parameters, and the user implements the upload process by himself, and calls onProgress, onError, and onSuccess in the customRequest input parameters when appropriate to update the internal state of the Upload component
+customRequest contains the following input parameters
+
+```ts
+{
+     // current file name
+     fileName: string,
+     // props.data set by the user
+     data: object,
+     // FileItem, refer to the following document for the specific structure
+     file: FileItem,
+     // original File Object which extends Blob, the file object actually obtained by the browser (https://developer.mozilla.org/zh-CN/docs/Web/API/File)
+     fileInstance: File,
+     // Function that should be called during upload, event needs to include total and loaded attributes
+     onProgress: (event: {total: number, loaded: number }) => any,
+     // Function to be called when upload error
+     onError: (userXhr: {status: number }, e: event) => any,
+      // The function that should be called after the upload is successful, response is the request result after the upload is successful
+     onSuccess: (response: any, e: event) => any,
+     // props.withCredentials set by the user
+     withCredentials: boolean,
+     // props.action set by the user
+     action: string,
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const mockRequest = ({ file, onProgress, onError, onSuccess }) => {
+        let count = 0;
+        let interval = setInterval(() => {
+            if (count === 100) {
+                clearInterval(interval);
+                onSuccess();
+                return;
+            }
+            onProgress({ total: 100, loaded: count });
+            count += 20;
+        }, 500);
+    };
+
+    return (
+        <Upload action="//semi.design/api/upload" customRequest={mockRequest}>
+            <Button icon={<IconUpload />} theme="light">
+                Click upload
+            </Button>
+        </Upload>
+    );
+};
+```
+
+## API Reference
+
+---
+
+|Property | Description | Type | Default Value | Version |
+|--- | --- | --- | --- | --- |
+|accept | `html` Native attribute, accept uploaded [file type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept). <br/>The value of `accept` is the [MIME types string](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types) or file that you allow to select the file Suffix (.jpg, etc.) | string | | |
+|action | File upload address, required | string | | |
+|afterUpload | Hook after the file upload, update the file status according to the returned object | function(auProps) => afterUploadResult | | 1.0.0 |
+|beforeClear|Call back before clearing the file, judge whether to continue removing according to the return value, return false, Promise.resolve(false), Promise.reject() will prevent removal|(fileList: Array<FileItem \>) => boolean \| Promise||1.31.0|
+|beforeRemove|Callback before removing the file, judge whether to continue removing according to the return value, return false, Promise.resolve(false), Promise.reject() will prevent removal|(file: <FileItem\>, fileList: Array<FileItem \>) => boolean \| Promise||1.31.0|
+|beforeUpload | The hook before uploading the file, according to the return object to update the file status, control whether to upload | function(buProps) => beforeUploadResult \| Promise \| boolean | | 1.0.0 |
+|capture | The way of media shooting in the file upload control | boolean \| string \| undefined | | |
+|className | class name | string | | |
+|customRequest | Asynchronous request method for custom upload | (object: customRequestArgs) => void | | 1.5.0 |
+|data | Additional parameters attached to the upload or the method to return the uploaded additional parameters| object\|(file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) => object | {} | |
+|defaultFileList | List of uploaded files | Array<FileItem\> | [] | |
+|directory | Folder type upload | boolean | false | 1.20.0 |
+|disabled | Whether to disable | boolean | false | |
+|dragIcon | Icon on the left side of the drag area | ReactNode | `<IconUpload />` | 0.22.0 |
+|dragMainText | Main text of the drag area | ReactNode |'Click to upload the file or drag and drop the file here' | 0.22.0 |
+|dragSubText | Drag area help text | ReactNode |'' | 0.22.0 |
+|draggable | Whether to support drag and drop upload | boolean | false | 0.22.0 |
+|fileList | A list of uploaded files. When this value is passed in, upload is a controlled component | Array<FileItem\> | | 1.0.0 |
+|fileName | has the same function as name and is mainly used in Form.Upload. In order to avoid conflicts with the props.name of Field, a renamed props is provided here | string | | 1.0.0 |
+|headers | The headers attached to the upload or the method to return the uploaded additional headers| object\|(file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) = > object | {} | |
+|itemStyle | Inline style of fileCard | CSSProperties | | 1.0.0 |
+|limit | Maximum number of files allowed to be uploaded | number | | |
+|listType | File list display type, optional `picture`, `list` | string |'list' | |
+|maxSize | Maximum file size limit, in KB | number | | |
+|minSize | Minimum file size limit, unit KB | number | | |
+|multiple | Whether to allow multiple files to be selected at a time | boolean | false | |
+|name | File name used when uploading | string |'' | |
+|onAcceptInvalid | Triggered when the received file does not conform to the accept specification (generally because the folder selects all types of files / drags and drops files that do not conform to the format) | (files: File[]) => void | | 1.24 .0 |
+|onChange | Called when the file status changes, including upload success, failure, upload, the callback input parameter is Object, including fileList, currentFile, etc.| ({fileList: Array<FileItem\>, currentFile?: FileItem}) = > void | | 1.0.0 |
+|onClear | Callback when click to clear | () => void | | 1.1.0 |
+|onDrop | Triggered when the dragged element is released on the drag area | (e, files: Array<File\>, filelist: Array<FileItem\>) => void | | 1.9.0 |
+|onError | Callback when uploading error| (error: Error, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList: Array<FileItem\> , xhr: XMLHttpRequest) => void | | |
+|onExceed | Callback when the total number of uploaded files exceeds `limit` | (fileList:Array<FileItem\>) => void | | |
+|onFileChange | Callback after file selection | (Array<File\>) => void | | |
+|onOpenFileDialog | Triggered when opening the system file system file selection pop-up window | () => void | | 1.18.0 |
+|onPreviewClick | Callback when the file card is clicked | (fileItem: FileItem) => void | | 1.8.0 |
+|onProgress | Callback when uploading files| (percent: number, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList: Array<FileItem\> ) => void | | |
+|onRemove | Callback for removing files| (currentFile: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\>, currentFileItem: FileItem ) => void | | |
+|onRetry | Upload retry callback | (file: <FileItem\>) => void | | 1.18.0 |
+|onSizeError | File size invalid callback| (file:[File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\>) => void | | |
+|onSuccess | Callback after successful upload| (responseBody: object, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\> ) => void | |
+|previewFile | Customize the preview logic, the content returned by this function will replace the original thumbnail | (fileItem: FileItem) => ReactNode | | |
+|prompt | Custom slot, which can be used to insert prompt text. Different from writing directly in `children`, the content of `prompt` will not trigger upload when clicked.<br/>(In the picture wall mode, the incoming prompt is only supported after v1.3.0) | ReactNode | | |
+|promptPosition | The position of the prompt text. When the listType is list, the reference object is the children element; when the listType is picture, the reference object is the picture list. Optional values ​​`left`, `right`, `bottom`<br/> (In picture wall mode, promptPosition is only supported after v1.3.0) | string |'right' | |
+|renderFileItem | Custom rendering of fileCard | (renderProps: RenderFileItemProps) => ReactNode | | 1.0.0 |
+|showClear | When limit is not 1 and the current number of uploaded files is greater than 1, whether to show the clear button | boolean | true | 1.0.0 |
+|showReplace | When the upload is successful, whether to display the replace button inside the fileCard | boolean | false | 1.21.0 |
+|showRetry | When uploading fails, whether to display the retry button inside the fileCard | boolean | true | 1.0.0 |
+|showUploadList | Whether to display the file list | boolean | true | |
+|style | Style | CSSProperties | | |
+|transformFile | After selecting the file, the callback function before uploading the file can be used to customize the conversion processing of the file | (file:[File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) => FileItem | | 1.0.0 |
+|uploadTrigger | Trigger upload timing, optional values ​​`auto`, `custom` | string |'auto' | |
+|validateMessage | Upload the overall error message | ReactNode | | 1.0.0 |
+|withCredentials | Whether to bring cookie information | boolean | false | |
+
+## Interfaces
+
+### FileItem Interface
+
+<Notice title='Notice'>
+    uid is the unique identifier of the file, and upload update and delete logic strongly relies on this value.
+    If the current file is selected and added by upload, uid will be automatically generated.
+    If it is passed in by props.defaultFileList or props.fileList, it must be passed, and you need to ensure that it will not be repeated
+</Notice>
+
+```ts
+interface FileItem {
+    event?: event, // xhr event
+    fileInstance?: File, // original File Object which extends Blob, the file object actually obtained by the browser (https://developer.mozilla.org/zh-CN/docs/Web/API/File)
+    name: string,
+    percent?: number, // upload progress percentage
+    preview: boolean, // Whether to preview according to url
+    response?: any, // xhr's response, response body when the request is successful, and corresponding error when the request fails
+    shouldUpload?: boolean; // Should you continue to upload
+    showReplace?: boolean, // Separately control whether the file displays the replace button
+    showRetry?: boolean, // Separately control whether the file displays the retry button
+    size: string, // file size, unit kb
+    status: string, //'success' |'uploadFail' |'validateFail' |'validating' |'uploading' |'wait';
+    uid: string, // The unique identifier of the file. If the current file is selected and added by upload, the uid will be automatically generated. If it is defaultFileList, you need to ensure that it will not be repeated
+    url: string,
+    validateMessage?: ReactNode | string,
+}
+```
+
+## Design Tokens
+<DesignToken/>
+
+## FAQ
+
+- When will the retry button appear?
+    - When `showRetry` is true and the upload of the current file fails due to a network error, the retry button will be displayed. Other statuses such as verification failed, upload successful, etc. will not display the retry button.
+- When will the replace button appear?
+    - When `showReplace` is true and the current file status is uploaded, the replace button will be displayed.
+- Where did Semi save the pictures?
+    - Semi is not responsible for the preservation of the image, you need to customize the action when you use the Upload component. You can choose to set action as your own server address or image service address.
+- Didn’t call the XXX method after uploading the picture?
+    - If you set `accept`, you can try to remove the accept attribute, and then see if the modified method is called. After removing it, the method is called to explain that the file type obtained by accept in the current environment does not match the set accept, and the upload behavior is terminated early. You can make a breakpoint to upload/foundation.js checkFileFormat function to see if the actual value of file.type obtained meets expectations.
+
+<Notice title={"About the progress bar"}>The progress bar indicates the upload progress. The upload progress is divided into two parts: data upload and server return. If all the data has been sent, but the server does not return a response, the progress bar will stay at 90%. The user upload is not completed. At this time, the request in the developer tool will be pending, which is normal. </Notice>
+
+<!-- ## Related Material
+
+```material
+82
+``` -->

+ 1181 - 0
content/input/upload/index.md

@@ -0,0 +1,1181 @@
+---
+localeCode: zh-CN
+order: 32
+category: 输入类
+title: Upload 上传
+icon: doc-upload
+width: 48%
+brief: 文件选择上传
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Upload } from '@douyinfe/semi-ui';
+```
+### 基本
+
+最基本的用法,在 children 内放置一个 Button,点击 children 内容(即放置的 Button)激活文件选择框,选择完成后自动开始上传
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+<Upload action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859">
+    <Button icon={<IconUpload />} theme="light">
+        点击上传
+    </Button>
+</Upload>
+```
+
+### 添加提示文本
+
+通过`prompt`插槽,设置自定义提示文本  
+通过`promptPosition`设置插槽位置,可选`left`、`right`、`bottom`,默认为`right`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    const getPrompt = (pos, isListType) => {
+        let basicStyle = { display: 'flex', alignItems: 'center', color: 'grey', height: isListType ? '100%' : 32 };
+        let marginStyle = {
+            left: { marginRight: 10 },
+            right: { marginLeft: 10 },
+        };
+        let style = { ...basicStyle, ...marginStyle[pos] };
+
+        return <div style={style}>请上传资格认证材料</div>;
+    };
+    const button = (
+        <Button icon={<IconUpload />} theme="light">
+            {' '}
+            点击上传{' '}
+        </Button>
+    );
+    const positions = ['right', 'left', 'bottom'];
+    return (
+        <>
+            {positions.map((pos, index) => (
+                <>
+                    {index ? (
+                        <div
+                            style={{ marginBottom: 12, marginTop: 12, borderBottom: '1px solid var(--semi-color-border)' }}
+                        ></div>
+                    ) : null}
+                    <Upload action={action} prompt={getPrompt(pos)} promptPosition={pos}>
+                        {button}
+                    </Upload>
+                </>
+            ))}
+        </>
+    );
+};
+```
+
+当 listType 为 picture 时,promptPosition 位置的参照对象为图片墙列表整体
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    const action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    const getPrompt = (pos, isListType) => {
+        let basicStyle = { display: 'flex', alignItems: 'center', color: 'grey', height: isListType ? '100%' : 32 };
+        let marginStyle = {
+            left: { marginRight: 10 },
+            right: { marginLeft: 10 },
+        };
+        let style = { ...basicStyle, ...marginStyle[pos] };
+
+        return <div style={style}>请上传萌宠认证材料</div>;
+    };
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'jiafang1.jpeg',
+            status: 'success',
+            size: '130kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
+        },
+        {
+            uid: '2',
+            name: 'jiafang2.jpeg',
+            size: '222kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
+        },
+        {
+            uid: '5',
+            name: 'jiafang3.jpeg',
+            percent: 50,
+            size: '222kb',
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg',
+        },
+    ];
+    const positions = ['right', 'bottom'];
+    return (
+        <>
+            {positions.map((pos, index) => (
+                <>
+                    {index ? (
+                        <div
+                            style={{ marginBottom: 12, marginTop: 12, borderBottom: '1px solid var(--semi-color-border)' }}
+                        ></div>
+                    ) : null}
+                    <Upload
+                        action={action}
+                        prompt={getPrompt(pos, true)}
+                        promptPosition={pos}
+                        listType="picture"
+                        defaultFileList={defaultFileList}
+                    >
+                        <IconPlus size="extra-large" />
+                    </Upload>
+                </>
+            ))}
+        </>
+    );
+};
+```
+
+### 点击头像触发上传
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Avatar, Toast } from '@douyinfe/semi-ui';
+import { IconCamera } from '@douyinfe/semi-icons';
+
+() => {
+    const [url, setUrl] = useState('https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg');
+    const onSuccess = (response, file) => {
+        Toast.success('头像更新成功');
+        setUrl('https://sf6-cdn-tos.douyinstatic.com/obj/ttfe/ies/semi/ttmoment.jpeg');
+    };
+
+    const style = {
+        backgroundColor: 'rgba(0,0,0,.4)',
+        height: '100%',
+        width: '100%',
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'center',
+        color: '#FFF',
+    };
+    
+    const hoverMask =  (<div style={style}>
+        <IconCamera />
+    </div>);
+
+    const api = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    let imageOnly = 'image/*';
+
+    return (
+        <Upload
+            className="avatar-upload"
+            action={api}
+            onSuccess={onSuccess}
+            accept={imageOnly}
+            showUploadList={false}
+            onError={() => Toast.error('上传失败')}
+        >
+            <Avatar src={url} style={{ margin: 4 }} hoverMask={hoverMask} />
+        </Upload>
+    )
+}
+```
+
+```css
+.avatar-upload .semi-upload-add {
+    border-radius: 50%; // 确保只有圆是点击热区
+}
+```
+
+### 自定义上传属性
+
+通过设置 `data`、`headers` 可添加自定义上传属性
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    let data = {
+        role: 'ies',
+        time: new Date().getTime(),
+    };
+    let headers = {
+        'x-tt-semi': 'semi-upload',
+    };
+    return (
+        <Upload action={action} data={data} headers={headers}>
+            <Button icon={<IconUpload />} theme="light">
+                点击上传
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### 上传文件类型
+
+通过 `accept 属性(`input` 的原生 `html` 属性)可以限制上传的文件类型。
+
+`accept` 支持传入以下两种类型字符串:
+
+- 文件后缀名集合(推荐),如 .jpg、.png 等;
+- 文件类型的 MIME types 集合,可参考[MDN 文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types)  
+
+例如只允许用户上传 PNG 和 PDF 文件,`accept` 可以这样写: `accept = '.pdf,.png'` 或 `accept = 'application/pdf,image/png'`(将 PNG 与 PDF 的 MIME type 通过`,`连接起来即可)。
+
+<Notice type="primary" title="注意事项">
+    <div>Upload 会在内部拦截掉不符合 accept 格式的文件,当拦截到不符合格式要求的文件时,会触发 onAcceptInvalid 方法(v1.24提供);</div>
+    <div>accept 使用后缀可以避免因为浏览器或者操作系统的不同导致 file.type 与 MIME 不兼容问题。</div>
+</Notice>
+
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    let imageOnly = 'image/*';
+    let videoOnly = 'video/*';
+    let fileLimit = '.pdf,.png,.jpeg';
+    return (
+        <>
+            <Upload action={action} accept={imageOnly} style={{ marginBottom: 12 }}>
+                <Button icon={<IconUpload />} theme="light">
+                    上传图片
+                </Button>
+            </Upload>
+            <Upload action={action} accept={videoOnly} style={{ marginBottom: 12 }}>
+                <Button icon={<IconUpload />} theme="light">
+                    上传视频
+                </Button>
+            </Upload>
+            <Upload action={action} accept={fileLimit}>
+                <Button icon={<IconUpload />} theme="light">
+                    上传 PDF, PNG, JPEG
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### 上传文件夹
+
+通过传入`directory`为`true`,可以支持上传文件夹下的所有文件
+
+```jsx live=true
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    return (
+        <>
+            <Upload action={action} directory>
+                <Button icon={<IconUpload />} theme="light">
+                    上传文件夹
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### 一次选中多个文件
+
+通过设置 `multiple` 属性可以支持同时选中多个文件上传。
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    return (
+        <Upload action={action} multiple>
+            <Button icon={<IconUpload />} theme="light">
+                点击上传
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### 限制文件总数量
+
+通过设置 `limit` 属性可以限制最大可上传的文件数  
+当`limit`为1时,始终用最新上传的代替当前,并不会触发onExceed回调**v1.5.0生效**
+
+```jsx dir="column" live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https:https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    let limit = 1;
+    let onChange = props => {
+        console.log(props.fileList)
+    };
+    return (
+        <Upload
+            action={action}
+            limit={limit}
+            onChange={onChange}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                点击上传(最多{limit}项)
+            </Button>
+        </Upload>
+    );
+};
+```
+
+```jsx dir="column" live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https:https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    let [disabled, setDisabled] = useState(false);
+    let limit = 2;
+    let onChange = props => {
+        let length = props.fileList.length;
+        if (length === limit) {
+            setDisabled(true);
+        } else {
+            setDisabled(false);
+        }
+    };
+    return (
+        <Upload
+            action={action}
+            limit={limit}
+            onExceed={() => Toast.warning(`最多只允许上传${limit}个文件`)}
+            onChange={onChange}
+        >
+            <Button icon={<IconUpload />} theme="light" disabled={disabled}>
+                点击上传(最多{limit}项)
+            </Button>
+        </Upload>
+    );
+};
+```
+
+照片墙模式下,当已上传文件数量等于 limit 时,会自动隐藏上传入口
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'success',
+            size: '222KB',
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'tiktok.jpeg', { type: 'image/png' }),
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/a0ca113c9c6d4fb49c9b8bb54a392a00~noop.image',
+        },
+    ];
+    return (
+        <Upload
+            action={action}
+            limit={2}
+            listType="picture"
+            accept="image/*"
+            defaultFileList={defaultFileList}
+            onExceed={() => Toast.warning('最多只允许上传2个文件')}
+        >
+            <IconPlus size="extra-large" />
+        </Upload>
+    );
+};
+```
+
+### 限制上传文件大小
+
+通过 `maxSize` 和 `minSize` 属性可以自定义上传文件大小的限制,通过设置 `onSizeError` 可以设置超出限制时的回调。
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+
+    return (
+        <>
+            <Upload
+                action={action}
+                maxSize={1024}
+                minSize={200}
+                onSizeError={(file, fileList) => Toast.error(`${file.name} size invalid`)}
+            >
+                <Button icon={<IconUpload />} theme="light">
+                    点击上传(最小 200KB,最大 1MB)
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### 自定义预览逻辑
+
+`listType`为`list`时,可以通过传入 `previewFile` 览逻辑。  
+例如你不需要对图片类型进行缩略图预览时,可以在 `previewFile` 中恒定返回一个`<IconFile />`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload, IconFile } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+    ];
+    return (
+        <Upload
+            defaultFileList={defaultFileList}
+            action={action}
+            previewFile={file => <IconFile size="large" />}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                点击上传
+            </Button>
+        </Upload>
+    );
+};
+```
+
+### 默认文件列表
+
+通过 `defaultFileList` 可以展示已上传的文件。当需要预览默认文件的缩略图时,你可以将 `defaultFileList` 内对应 `item` 的 `preview` 属性设为 `true`
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/c2a65140483e4a20802d64af5fec1b39~noop.image',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'uploadFail',
+            size: '222KB',
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'tiktok.jpeg', { type: 'image/png' }),
+            url: 'https://sf6-cdn-tos.douyinstatic.com/img/ee-finolhu/a0ca113c9c6d4fb49c9b8bb54a392a00~noop.image',
+        },
+    ];
+
+    return (
+        <>
+            <Upload action={action} defaultFileList={defaultFileList}>
+                <Button icon={<IconUpload />} theme="light">
+                    点击上传
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### 受控组件
+
+当传入`fileList`时,作为受控组件使用。需要监听 onChange 回调,并且将 fileList 回传给 Upload(注意需传入一个新的数组对象)
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const initList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'validateFail',
+            size: '222KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg',
+        },
+        {
+            uid: '3',
+            name: 'jiafang.jpeg',
+            status: 'uploading',
+            size: '222KB',
+            percent: 50,
+            preview: true,
+            fileInstance: new File([new ArrayBuffer(2048)], 'jiafang.jpeg', { type: 'image/jpeg' }),
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/4a55704fb0b8b85eaccdb4ed22469f57.jpg',
+        },
+    ];
+
+    const [list, updateList] = useState(initList);
+
+    const onChange = ({ fileList, currentFile, event }) => {
+        console.log('onChange');
+        console.log(fileList);
+        console.log(currentFile);
+        let newFileList = [...fileList]; // spread to get new array
+        updateList(newFileList);
+    }
+
+    return (
+        <Upload
+            action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859"
+            onChange={onChange}
+            fileList={list}
+            showRetry={false}
+        >
+            <Button icon={<IconUpload />} theme="light">
+                点击上传
+            </Button>
+        </Upload>
+    )
+}
+```
+
+### 照片墙
+
+设置 `listType = 'picture'`,用户可以上传图片并在列表中显示缩略图
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconPlus } from '@douyinfe/semi-icons';
+
+() => {
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'jiafang.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url:
+                'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+    ];
+    return (
+        <>
+            <Upload action={action} listType="picture" accept="image/*" multiple defaultFileList={defaultFileList}>
+                <IconPlus size="extra-large" />
+            </Upload>
+        </>
+    );
+};
+```
+
+### 禁用
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const defaultFileList = [
+        {
+            uid: '1',
+            name: 'vigo.png',
+            status: 'success',
+            size: '130KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/e82f3b261133d2b20d85e8483c203112.jpg',
+        },
+        {
+            uid: '2',
+            name: 'tiktok.jpeg',
+            status: 'validateFail',
+            size: '222KB',
+            preview: true,
+            url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
+        },
+    ];
+    let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+    return (
+        <>
+            <Upload action={action} disabled defaultFileList={defaultFileList}>
+                <Button icon={<IconUpload />} theme="light" disabled>
+                    点击上传
+                </Button>
+            </Upload>
+        </>
+    );
+};
+```
+
+### 手动触发上传
+
+`uploadTrigger='custom'`,选中文件后将不会自动触发上传。需要手动调用 `ref` 上的 `upload` 方法触发
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload, IconPlus } from '@douyinfe/semi-icons';
+
+class ManulUploadDemo extends React.Component {
+    constructor() {
+        super();
+        this.manulUpload = this.manulUpload.bind(this);
+        this.uploadRef = React.createRef();
+    }
+
+    manulUpload() {
+        this.uploadRef.current.upload();
+    }
+
+    render() {
+        let action = 'https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859';
+        return (
+            <div>
+                <Upload
+                    accept="image/gif, image/png, image/jpeg, image/bmp, image/webp"
+                    action={action}
+                    uploadTrigger="custom"
+                    ref={this.uploadRef}
+                    onSuccess={(...v) => console.log(...v)}
+                    onError={(...v) => console.log(...v)}
+                >
+                    <Button icon={<IconPlus />} theme="light" style={{ marginRight: 8 }}>
+                        选择文件
+                    </Button>
+                    <Button icon={<IconUpload />} theme="light" onClick={this.manulUpload}>
+                        开始上传
+                    </Button>
+                </Upload>
+            </div>
+        );
+    }
+}
+```
+
+### 拖拽上传
+
+`draggable='true'`,可以使用拖拽功能
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+
+() => (
+    <Upload
+        action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859"
+        draggable={true}
+        dragMainText={'点击上传文件或拖拽文件到这里'}
+        dragSubText="支持任意类型文件"
+    ></Upload>
+);
+```
+
+可以通过`dragIcon`、`dragMainText`、`dragSubText` 快捷设置拖拽区内容
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconBolt } from '@douyinfe/semi-icons';
+
+() => <Upload
+    action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859"
+    dragIcon={<IconBolt />}
+    draggable={true}
+    accept="application/pdf,.jpeg"
+    dragMainText={'点击上传文件或拖拽文件到这里'}
+    dragSubText="仅支持jpeg、pdf"
+    style={{ marginTop: 10 }}
+></Upload>
+```
+
+还可以通过`children`传入 ReactNode,完全自定义拖拽区的显示
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload } from '@douyinfe/semi-ui';
+import { IconBolt } from '@douyinfe/semi-icons';
+
+() => (<Upload
+    action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859"
+    dragIcon={<IconBolt />}
+    draggable={true}
+    accept="application/pdf,.jpeg"
+    style={{ marginTop: 10 }}
+>
+    <div className="components-upload-demo-drag-area">
+        <img
+            src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/0f2a32f27eab90a296814fbc26103b2b.jpg"
+            height="96"
+            style={{ borderRadius: 4 }}
+        />
+        <div
+            style={{
+                fontSize: 14,
+                marginTop: 8,
+                flexBasis: '100%',
+                textAlign: 'center',
+                color: 'var(--semi-color-tertiary)',
+            }}
+        >
+            Wow, you can really dance.
+        </div>
+    </div>
+    </Upload>
+)
+```
+
+Scss 样式如下
+
+```scss
+.components-upload-demo-drag-area {
+    border-radius: var(--semi-border-radius-small);
+    border: 2px dashed var(--semi-color-border);
+    width: 100%;
+    padding: 12px;
+    background-color: var(--semi-color-tertiary-light-default);
+    display: flex;
+    cursor: pointer;
+    flex-wrap: wrap;
+    justify-content: center;
+    &:hover {
+        background-color: var(--semi-color-primary-light-default);
+        border-color: var(--semi-color-primary);
+    }
+}
+```
+
+### 上传前自定义校验
+
+可通过`beforeUpload`钩子,对文件状态进行更新,这是在网络上传前,选择文件后进行校验,`({ file: FileItem, fileList: Array<FileItem> }) => beforeUploadResult | Promise | boolean` 同步校验时需返回 boolean(true 为校验通过,false 为校验失败,校验失败会阻止文件网络上传)或者一个 Object 对象,具体结构如下
+
+```ts
+// beforeUploadResult:
+{
+    fileInstance?: File,
+    status?: 'success' | 'uploadFail' | 'validateFail' | 'validating' | 'uploading' | 'wait',
+    validateMessage?: React.ReactNode | string, // 文件的校验信息
+    shouldUpload: boolean, // 是否需要上传。默认为true,如果为false,该fileItem只会被展示在列表中,不会触发上传操作
+    autoRemove: boolean, // 是否从fileList中移除该文件,默认为false
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class ValidateDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.beforeUpload = this.beforeUpload.bind(this);
+        this.transformFile = this.transformFile.bind(this);
+        this.count = 0;
+    }
+
+    transformFile(fileInstance) {
+        if (this.count === 0) {
+            let newFile = new File([fileInstance], 'newFileName', { type: 'image/png' });
+            return newFile;
+        } else {
+            return fileInstance;
+        }
+    }
+
+    beforeUpload({ file, fileList }) {
+        let result;
+        if (this.count > 0) {
+            result = {
+                autoRemove: false,
+                fileInstance: file.fileInstance,
+                shouldUpload: true,
+            };
+        } else {
+            result = {
+                autoRemove: false,
+                fileInstance: file.fileInstance,
+                status: 'validateFail',
+                shouldUpload: false,
+            };
+        }
+        this.count = this.count + 1;
+        return result;
+    }
+
+    render() {
+        return (
+            <Upload
+                action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859"
+                transformFile={this.transformFile}
+                beforeUpload={this.beforeUpload}
+            >
+                <Button icon={<IconUpload />} theme="light">
+                    点击上传(上传前同步校验)
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+异步校验时,需返回 Promise,Promise reslove 代表检验通过,reject 代表校验失败,不会触发上传。  
+reslove/reject 时可以传入 object(结构同上 beforeUploadResult)
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class AsyncBeforeUploadDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.beforeUpload = this.beforeUpload.bind(this);
+        this.count = 0;
+    }
+
+    beforeUpload({ file, fileList }) {
+        let result;
+        return new Promise((reslove, reject) => {
+            if (this.count > 1) {
+                result = {
+                    autoRemove: false,
+                    shouldUpload: true,
+                };
+                this.count = this.count + 1;
+                reslove(result);
+            } else {
+                result = {
+                    autoRemove: false,
+                    fileInstance: file.fileInstance,
+                    status: 'validateFail',
+                    shouldUpload: false,
+                    validateMessage: `第${this.count + 1}个注定失败`,
+                };
+                this.count = this.count + 1;
+                reject(result);
+            }
+        });
+    }
+
+    render() {
+        return (
+            <Upload action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859" beforeUpload={this.beforeUpload}>
+                <Button icon={<IconUpload />} theme="light">
+                    点击上传(上传前异步校验)
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+### 上传后更新文件信息
+
+可以通过`afterUpload`钩子,对文件状态,校验信息,文件名进行更新。  
+`({ response: any, file: FileItem, fileList: Array<FileItem> }) => afterUploadResult`  
+afterUpload 在上传完成后(xhr.onload)且没有发生错误的情况下触发,需返回一个 Object 对象(不支持异步返回),具体结构如下
+
+```ts
+// afterUploadResult:
+{
+    status?: 'success' | 'uploadFail' | 'validateFail' | 'validating' | 'uploading' | 'wait',
+    validateMessage?: React.ReactNode | string, // 文件的校验信息
+    autoRemove: boolean, // 是否从fileList中移除该文件,默认为false
+    name: string,
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+class ValidateDemo extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.count = 0;
+    }
+
+    afterUpload({ response, file }) {
+        // 可以根据业务接口返回,决定当次上传是否成功
+        if (response.status_code === 200) {
+            return {
+                autoRemove: false,
+                status: 'uploadFail',
+                validateMessage: '内容不合法',
+                name: 'RenameByServer.jpg',
+            };
+        } else {
+            return {};
+        }
+    }
+
+    render() {
+        return (
+            <Upload action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859" afterUpload={this.afterUpload}>
+                <Button icon={<IconUpload />} theme="light">
+                    点击上传
+                </Button>
+            </Upload>
+        );
+    }
+}
+```
+
+### 自定义请求
+
+当传入 customRequest 时, 相当于使用的自定义的请求方法替换了 upload 内置的 xhr 请求,用户需要自行接管上传行为。  
+可在入参中获取到当前操作的 file 对象,用户自行实现上传过程,并且在适当的时候调用 customRequest 入参中的 onProgress、onError、onSuccess 以更新 Upload 组件内部状态  
+customRequest 包含以下入参
+
+```ts
+{
+    // 当前文件名称
+    fileName: string,
+    // 用户设置的props.data
+    data: object,
+    // FileItem,具体结构参考下面的文档
+    file: FileItem,
+    // original File Object which extends Blob, 浏览器实际获取到的文件对象(https://developer.mozilla.org/zh-CN/docs/Web/API/File)
+    fileInstance: File,
+    // 上传过程中应调用的函数,event需要包含 total、loaded属性
+    onProgress: (event: { total: number, loaded: number }) => any,
+    // 上传出错时应调用的函数
+    onError: (userXhr: { status: number }, e: event) => any,
+     // 上传成功后应调用的函数, response为上传成功后的请求结果
+    onSuccess: (response: any, e: event) => any,
+    // 用户设置的props.withCredentials
+    withCredentials: boolean,
+    // 用户设置的props.action
+    action: string,
+}
+```
+
+```jsx live=true width=48%
+import React from 'react';
+import { Upload, Button } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+
+() => {
+    const mockRequest = ({ file, onProgress, onError, onSuccess }) => {
+        let count = 0;
+        let interval = setInterval(() => {
+            if (count === 100) {
+                clearInterval(interval);
+                onSuccess();
+                return;
+            }
+            onProgress({ total: 100, loaded: count });
+            count += 20;
+        }, 500);
+    };
+
+    return (
+        <Upload action="https://run.mocky.io/v3/d6ac5c9e-4d39-4309-a747-7ed3b5694859" customRequest={mockRequest}>
+            <Button icon={<IconUpload />} theme="light">
+                点击上传
+            </Button>
+        </Upload>
+    );
+};
+```
+
+## API 参考
+
+---
+
+|属性 | 说明 | 类型 | 默认值 | 版本 |
+|--- | --- | --- | --- | --- |
+|accept | `html` 原生属性,接受上传的[文件类型](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept)。<br/>`accept` 的值为你允许选择文件的[MIME types 字符串](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types)或文件后缀(.jpg等) | string | |  |
+|action | 文件上传地址,必填 | string |  |  |
+|afterUpload | 文件上传后的钩子,根据 return 的 object 更新文件状态 | function(auProps) => afterUploadResult |  | 1.0.0 |
+|beforeClear|清空文件前回调,按照返回值来判断是否继续移除,返回false、Promise.resolve(false)、Promise.reject()会阻止移除|(fileList: Array<FileItem \>) => boolean \| Promise||1.31.0|
+|beforeRemove|移除文件前的回调,按照返回值来判断是否继续移除,返回false、Promise.resolve(false)、Promise.reject()会阻止移除|(file: <FileItem\>, fileList: Array<FileItem \>) => boolean \| Promise||1.31.0|
+|beforeUpload | 上传文件前的钩子,根据 return 的 object 更新文件状态,控制是否上传 | function(buProps) => beforeUploadResult \| Promise \| boolean |  | 1.0.0 |
+|capture | 文件上传控件中媒体拍摄的方式 | boolean \| string \| undefined | | |
+|className | 类名 | string |  |  |
+|customRequest | 自定义上传使用的异步请求方法 | (object: customRequestArgs) => void |  | 1.5.0 |
+|data | 上传时附带的额外参数或返回上传额外参数的方法 | object\|(file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) => object | {} |  |
+|defaultFileList | 已上传的文件列表 | Array<FileItem\> | [] |  |
+|directory | 文件夹类型上传 | boolean | false | 1.20.0 |
+|disabled | 是否禁用 | boolean | false |  |
+|dragIcon | 拖拽区左侧 Icon | ReactNode | `<IconUpload />` | 0.22.0 |
+|dragMainText | 拖拽区主文本 | ReactNode | '点击上传文件或拖拽文件到这里' | 0.22.0 |
+|dragSubText | 拖拽区帮助文本 | ReactNode | '' | 0.22.0 |
+|draggable | 是否支持拖拽上传 | boolean | false | 0.22.0 |
+|fileList | 已上传的文件列表,传入该值时,upload 即为受控组件 | Array<FileItem\> |  | 1.0.0 |
+|fileName | 作用与 name 相同,主要在 Form.Upload 中使用,为了避免与 Field 的 props.name 冲突,此处另外提供一个重命名的 props | string |  | 1.0.0 |
+|headers | 上传时附带的 headers 或返回上传额外 headers 的方法 | object\|(file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) => object | {} |  |
+|itemStyle | fileCard 的内联样式 | CSSProperties |  | 1.0.0 |
+|limit | 最大允许上传文件个数 | number |  |  |
+|listType | 文件列表展示类型,可选`picture`、`list` | string | 'list' |  |
+|maxSize | 文件体积最大限制,单位 KB | number |  |  |
+|minSize | 文件体积最小限制,单位 KB | number |  |  |
+|multiple | 是否允许单次选中多个文件 | boolean | false |  |
+|name | 上传时使用的文件名 | string | '' |  |
+|onAcceptInvalid | 当接收到的文件不符合accept规范时触发(一般是因为文件夹选择了全部类型文件/拖拽不符合格式的文件时触发) | (files: File[]) => void | | 1.24.0 |
+|onChange | 文件状态发生变化时调用,包括上传成功,失败,上传中,回调入参为 Object,包含 fileList、currentFile 等值 | ({fileList: Array<FileItem\>, currentFile?: FileItem}) => void |  | 1.0.0 |
+|onClear | 点击清空时的回调 | () => void |  | 1.1.0 |
+|onDrop | 当拖拽的元素在拖拽区上被释放时触发 | (e, files: Array<File\>, filelist: Array<FileItem\>) => void |  | 1.9.0 |
+|onError | 上传错误时的回调 | (error: Error, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList: Array<FileItem\>, xhr: XMLHttpRequest) => void |  |  |
+|onExceed | 上传文件总数超出 `limit` 时的回调 | (fileList:Array<FileItem\>) => void |  |  |
+|onFileChange | 选中文件后的回调 | (Array<File\>) => void |  |  |
+|onOpenFileDialog | 打开系统文系统文件选择弹窗时触发 | () => void |  | 1.18.0 |
+|onPreviewClick | 点击文件卡片时的回调 | (fileItem: FileItem) => void |  | 1.8.0 |
+|onProgress | 上传文件时的回调 | (percent: number, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList: Array<FileItem\>) => void |  |  |
+|onRemove | 移除文件的回调 | (currentFile: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\>, currentFileItem: FileItem) => void |  |  |
+|onRetry | 上传重试的回调 | (file: <FileItem\>) => void |  | 1.18.0 |
+|onSizeError | 文件尺寸非法的回调 | (file:[File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\>) => void |  |  |
+|onSuccess | 上传成功后的回调 | (responseBody: object, file: [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File), fileList:Array<FileItem\>) => void |  |
+|previewFile | 自定义预览逻辑,该函数返回内容将会替换原缩略图 | (fileItem: FileItem) => ReactNode |  |  |
+|prompt | 自定义插槽,可用于插入提示文本。与直接在 `children` 中写的区别时,`prompt` 的内容在点击时不会触发上传<br/>(图片墙模式下,v1.3.0 后才支持传入 prompt) | ReactNode |  |  |
+|promptPosition | 提示文本的位置,当 listType 为 list 时,参照物为 children 元素;当 listType 为 picture 时,参照物为图片列表。可选值 `left`、`right`、`bottom`<br/>(图片墙模式下,v1.3.0 后才支持使用 promptPosition) | string | 'right' |  |
+|renderFileItem | fileCard 的自定义渲染 | (renderProps: RenderFileItemProps) => ReactNode |  | 1.0.0 |
+|showClear | 在 limit 不为 1 且当前已上传文件数大于 1 时,是否展示清空按钮 | boolean | true | 1.0.0 |
+|showReplace | 上传成功时,是否展示在 fileCard 内部展示替换按钮 | boolean | false | 1.21.0 |
+|showRetry | 上传失败时,是否展示在 fileCard 内部展示重试按钮 | boolean | true | 1.0.0 |
+|showUploadList | 是否显示文件列表 | boolean | true |  |
+|style | 样式 | CSSProperties |  |  |
+|transformFile | 选中文件后,上传文件前的回调函数,可用于对文件进行自定义转换处理 | (file:[File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)) => FileItem |  | 1.0.0 |
+|uploadTrigger | 触发上传时机,可选值 `auto`、`custom` | string | 'auto' |  |
+|validateMessage | Upload 整体的错误信息 | ReactNode |  | 1.0.0 |
+|withCredentials | 是否带上 Cookie 信息 | boolean | false |  |
+
+
+## Interfaces
+### FileItem Interface
+
+<Notice title='注意'>
+    uid为文件唯一标识符,Upload的更新、删除等逻辑对该值强依赖。  
+    如果当前文件是通过upload选中添加的,会自动生成uid。  
+    如果是props.defaultFileList或者props.fileList传入的, 必传,且需要自行保证不会重复  
+</Notice>
+
+```ts
+interface FileItem {
+    event? : event,  // xhr event
+    fileInstance?: File, // original File Object which extends Blob, 浏览器实际获取到的文件对象(https://developer.mozilla.org/zh-CN/docs/Web/API/File)
+    name: string,
+    percent? : number, // 上传进度百分比
+    preview: boolean, // 是否根据url进行预览
+    response?: any, // xhr的response, 请求成功时为respoonse body,请求失败时为对应 error
+    shouldUpload?: boolean; // 是否应该继续上传
+    showReplace?: boolean, // 单独控制该file是否展示替换按钮
+    showRetry?: boolean, // 单独控制该file是否展示重试按钮
+    size: string, // 文件大小,单位kb
+    status: string, // 'success' | 'uploadFail' | 'validateFail' | 'validating' | 'uploading' | 'wait';
+    uid: string, // 文件唯一标识符,如果当前文件是通过upload选中添加的,会自动生成uid。如果是defaultFileList, 需要自行保证不会重复
+    url: string,
+    validateMessage?: ReactNode | string,
+}
+```
+
+### RenderFileItemProps Interface
+
+```ts
+interface RenderFileItemProps extends FileItem {
+    previewFile: (fileItem: FileItem) => ReactNode; // 自定义预览元素
+    listType: 'picture' | 'list'; // 文件列表展示类型
+    onRemove: () => void; // 移除
+    onRetry: () => void; // 重试
+    onReplace: () => void; // 替换文件
+    key: string; // Item key
+    showRetry: boolean; // 是否展示重试
+    showReplace: boolean; // 是否展示替换
+    style: CSSProperties; // 传入的itemStyle
+    disabled: boolean; // 是否禁用
+    onPreviewClick: () => void; // 点击预览
+}
+```
+
+## 设计变量
+<DesignToken/>
+
+
+## FAQ
+
+-   什么时候会展示重试按钮?
+    -   当 `showRetry` 为 true,且当前文件是由于网络原因错误导致的上传失败时,会展示重试按钮。其他如校验失败,上传成功等状态是不会展示重试按钮的。
+-   什么时候会展示替换按钮?
+    -   当 `showReplace` 为true,且当前文件状态为已上传时,会展示替换按钮。
+-   Semi Upload把图片存到哪里了?
+    -   Semi Upload不负责图片的保存,当你使用 Upload 组件时需要自定义 action。你可以选择把 action 设置为自己的服务器地址或者图片服务地址。
+-   Form.Upload props.name无效?
+    - Form.Field 中有props.name,Upload也有props.name,同名props会冲突。使用Form.Upload时,可以转为使用 props.fileName,避免冲突
+-   上传图片后没有调用 XXX 方法?
+    - 如果你设置了 `accept`,可以尝试把 accept 属性去掉,然后再看是否调用了改方法。去掉后调用了该方法说明,accept 在当前环境下获取的 file type 与设置的 accept 不符,上传行为提前终止。可以打个断点到 upload/foundation.js checkFileFormat 函数,看下获取的 file.type 真实值是否符合预期。
+
+<Notice title={"关于进度条"}>进度条表示上传进度,上传进度分为数据上载和服务器返回两部分,如果数据已经全部发出,但是服务器没有返回响应,进度条会停留在90%提示用户上传并没有完成,此时开发者工具中请求会处于 pending, 这是正常现象。仅当服务器返回响应,上传流程才真正结束,上传进度会达到100%</Notice>
+
+
+<!-- ## 相关物料
+
+```material
+82
+``` -->

+ 31 - 0
content/makeLn.js

@@ -0,0 +1,31 @@
+let exec = require('child_process').exec;
+let fs = require('fs');
+const executeShell = (command, callback) => {
+    exec(command, (error, stdout, stderr) => {
+        callback(stdout);
+    });
+};
+
+executeShell('find * | grep index', out => {
+    let fileList = out.split('\n');
+    fileList = fileList.map(file => {
+        return {
+            component: file.split('/')[1] === 'icon' ? 'icons' : file.split('/')[1],
+            filename: file.split('/')[2],
+            path: '../../../content/' + file,
+        };
+    });
+
+    const componentCodeList=fs.readdirSync('../packages/semi-ui');
+    const componentCodeListLowerCase=componentCodeList.map(dirName=>dirName.toLowerCase());
+    fileList.map(item => {
+        const index=componentCodeListLowerCase.indexOf(item.component);
+        let isExists = index!==-1;
+        if (isExists) {
+            let cmd = `ln -s -f ${item.path} ../packages/semi-ui/${componentCodeList[index]}/${item.filename}`;
+            executeShell(cmd, res => {
+                console.log(`exec ${cmd} ${res}`);
+            });
+        }
+    });
+});

+ 382 - 0
content/navigation/anchor/index-en-US.md

@@ -0,0 +1,382 @@
+---
+localeCode: en-US
+order: 33
+category: Navigation
+title:  Anchor
+subTitle: Anchor
+icon: doc-anchor
+brief: The Anchor component is used to create a hyper Link navigation bar.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx
+import { Anchor } from '@douyinfe/semi-ui';
+```
+
+### Basic Usage
+
+Use `Link` to create an anchor, click it to jump to the hash tag location.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor>
+        <Anchor.Link href="#Basic_Usage" title="Basic Usage" />
+        <Anchor.Link href="#Components" title="Components" />
+        <Anchor.Link href="#Design" title="Design" />
+        <Anchor.Link href="#Blocks" title="Blocks" />
+        <Anchor.Link href="#Theme" title="Theme" />
+    </Anchor>
+)
+```
+
+### Integrated Usage
+
+You can use `getContainer`, `targetOffset`, `offsetTop`, and `style` to create a out of the box hyperAnchor.Link navigation bar.
+
+-   getContainer:you can set the container of scroll content with `getContainer` property. Its default value is `window`.
+
+-   targetOffset: you can set the distance between the anchor point and the top of the container by setting `targetOffset`. **v>=1.9**
+
+-   style:the default `position` of Anchor is `relative`. You can customize it with `style` object.
+
+-   offsetTop:`offsetTop` can trigger the current Link switch when the scrolling content reaches a specified offset from the top of the container.
+
+```jsx
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <span>See the fixed Anchor on the right </span>
+            <Anchor
+                getContainer={getContainer}
+                offsetTop={100}
+                targetOffset={100} // v>=1.9
+                style={{ position: 'fixed', right: '20px', top: '100px', width: '200px', zIndex: 3}} >
+                <Anchor.Link href="#Basic_Usage" title="Fixed Anchor" />
+                <Anchor.Link href="#Integrated_Usage" title="Integrated Usage" />
+                <Anchor.Link href="#Size" title="Size" />
+                <Anchor.Link href="#Rail_Theme" title="Rail Theme" />
+                <Anchor.Link href="#Auto_Collapse" title="Auto Collapse" />
+                <Anchor.Link href="#Show_Tooltip" title="Show Tooltip" />
+                <Anchor.Link href="#Tooltip_Position" title="Tooltip Position" />
+                <Anchor.Link href="#API_Reference" title="API Reference">
+                    <Anchor.Link href="#Anchor" title="Anchor" />
+                    <Anchor.Link href="#Anchor.Link" title="Anchor.Link" />
+                </Anchor.Link>
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### Size
+
+You can change Anchor size with `size` property.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor size={'default'}>
+        <Anchor.Link href="#Components" title="Components" />
+        <Anchor.Link href="#Design" title="Design" />
+        <Anchor.Link href="#Blocks" title="Blocks" />
+        <Anchor.Link href="#Theme" title="Theme" />
+    </Anchor>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor size={'small'}>
+        <Anchor.Link href="#Components" title="Components" />
+        <Anchor.Link href="#Design" title="Design" />
+        <Anchor.Link href="#Blocks" title="Blocks" />
+        <Anchor.Link href="#Theme" title="Theme" />
+    </Anchor>
+)
+```
+
+### Rail Theme
+
+You can change rail color with `railTheme` property. Three themes are supported and the default value is `primary`.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'primary'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}>
+                <Anchor.Link href="#Size" title="Size" />
+                <Anchor.Link href="#Rail_Theme" title="Rail Theme" />
+                <Anchor.Link href="#Design" title="Design" />
+                <Anchor.Link href="#Blocks" title="Blocks" />
+                <Anchor.Link href="#Theme" title="Theme" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'tertiary'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}>
+                <Anchor.Link href="#Size" title="Size" />
+                <Anchor.Link href="#Rail_Theme" title="Rail Theme" />
+                <Anchor.Link href="#Design" title="Design" />
+                <Anchor.Link href="#Blocks" title="Blocks" />
+                <Anchor.Link href="#Theme" title="Theme" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'muted'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}>
+                <Anchor.Link href="#Size" title="Size" />
+                <Anchor.Link href="#Rail_Theme" title="Rail Theme" />
+                <Anchor.Link href="#Design" title="Design" />
+                <Anchor.Link href="#Blocks" title="Blocks" />
+                <Anchor.Link href="#Theme" title="Theme" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### Auto Collapse
+
+Anchor can dynamically display child links with `autoCollapse` property. The default is `false`.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+        <Anchor
+            autoCollapse={true}
+            getContainer={getContainer}
+            targetOffset={60}
+            offsetTop={100}>
+            <Anchor.Link href="#Auto_Collapse" title="1. Auto Collapse">
+                <Anchor.Link href="#Components" title="1.1 Components">
+                    <Anchor.Link href="#Avatar" title="1.1.1 Avatar" />
+                    <Anchor.Link href="#Button" title="1.1.2 Button" />
+                    <Anchor.Link href="#Icon" title="1.1.3 Icon" />
+                </Anchor.Link>
+                <Anchor.Link href="#Blocks" title="1.2 Blocks" />
+                <Anchor.Link href="#Theme" title="1.3 Theme" />
+            </Anchor.Link>
+            <Anchor.Link href="#Design" title="2. Design" />
+        </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                autoCollapse={false}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}>
+                <Anchor.Link href="#Auto_Collapse" title="1. Auto Collapse">
+                    <Anchor.Link href="#Components" title="1.1 Components">
+                        <Anchor.Link href="#Avatar" title="1.1.1 Avatar" />
+                        <Anchor.Link href="#Button" title="1.1.2 Button" />
+                        <Anchor.Link href="#Icon" title="1.1.3 Icon" />
+                    </Anchor.Link>
+                    <Anchor.Link href="#Blocks" title="1.2 Blocks" />
+                    <Anchor.Link href="#Theme" title="1.3 Theme" />
+                </Anchor.Link>
+                <Anchor.Link href="#Design" title="2. Design" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### Show Tooltip
+
+`showTooltip` can display the title of link when it exceeds the max-width. The default value is `false`.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+        <Anchor
+            showTooltip={true}
+            getContainer={getContainer}
+            targetOffset={60}
+            offsetTop={100}
+        >
+            <Anchor.Link href="#Show_Tooltip" title="Tooltip is a useful tool that displays the entire content when text is abbreviated." />
+            <Anchor.Link href="#Components" title="Components" />
+            <Anchor.Link href="#Design" title="Design" />
+            <Anchor.Link href="#Blocks" title="Blocks" />
+            <Anchor.Link href="#Theme" title="Theme" />
+        </Anchor>
+        </div>
+    )
+}
+```
+
+### Tooltip Position
+
+You can change the Tooltip position with `position` property. It only works when `showTooltip` is `true`.
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+        <Anchor
+            showTooltip={true}
+            position={'right'}
+            getContainer={getContainer}
+            targetOffset={60}
+            offsetTop={100}
+        >
+            <Anchor.Link href="#Tooltip_Position" title="Tooltip is a useful tool that displays the entire content when text is abbreviated." />
+            <Anchor.Link href="#Components" title="Components" />
+            <Anchor.Link href="#Design" title="Design" />
+            <Anchor.Link href="#Blocks" title="Blocks" />
+            <Anchor.Link href="#Theme" title="Theme" />
+        </Anchor>
+        </div>
+    )
+}
+```
+
+## API Reference
+
+### Anchor
+
+| PROPERTIES   | INSTRUCTIONS                                                                                                        | TYPE                                | DEFAULT   |  VERSION |
+| ------------ | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | --------- | - |
+| autoCollapse | Dynamically display child link                                                                                      | boolean                             | false     | |
+| className    | Class name                                                                                                          | string                              | -         | |
+| defaultAnchor | Default highlight anchor                                     | string                              | -         | 1.20.0 |
+| getContainer | Scroll container                                                                                                    | () => HTMLElement                   | window    | |
+| maxHeight    | max-height of Anchor                                                                                                | string \| number                    | `750px`   | |
+| maxWidth     | max-width of Anchor                                                                                                 | string \| number                    | `200px`   | |
+| offsetTop    | Trigger the current link switch when the scrolling content reaches a specified offset from the top of the container | number                              | 0         | |
+| onChange     | Change event                                                                                                        | (currentLink, previousLink) => void | -         | |
+| onClick      | Click event                                                                                                         | (event, currentLink) => void        | -         | |
+| position     | Tooltip position,same as `position` property of Tooltip component                                                  | string                              | -         | |
+| railTheme    | Style of scroll rail,one of `primary`,`tertiary`,`muted`                                                         | string                              | `primary` | |
+| scrollMotion | Animation of scroll behavior                                                                                        | boolean                             | false     | |
+| showTooltip  | Show Tooltip                                                                                                        | boolean                             | false     | |
+| size         | Size of Anchor,one of `small`,`default`                                                                           | string                              | `default` | |
+| style        | Style object                                                                                                        | object                              | -         | |
+| targetOffset | Anchor offset from top of target                                                                     | number                              | 0         | 1.9.0 |
+
+### Anchor.Link
+
+| PROPERTIES | INSTRUCTIONS              | TYPE              | DEFAULT |
+| ---------- | ------------------------- | ----------------- | ------- |
+| className  | Class name                | string            | -       |
+| href       | The target of hyper link  | string            | -       |
+| style      | Style object              | object            | -       |
+| title      | The content of hyper link | string\|ReactNode | -       |
+
+## Design Tokens
+<DesignToken/>
+
+## FAQ
+
+1. **Why didn't my link highlight and slide to follow?**  
+    Check whether you can scroll to the specified position by clicking the anchor:
+    - No, it means there is a problem with the id. check whether the id exists in the document;
+    - Yes, it may be that the scrolling container is not set correctly to ensure that the content of the document is wrapped in the scrolling container. The default scrolling container is window. If your container is a div of .my-container, you should set the scrolling container to this div.
+    
+    ```jsx
+    function() {
+        const getContainer = () => {
+            return document.querySelector('.my-container');
+        }
+        return (
+            <Anchor
+                /* Other props */
+                getContainer={getContainer}
+                >
+                /* Links */
+            </Anchor>
+        )
+    }
+    ```

+ 385 - 0
content/navigation/anchor/index.md

@@ -0,0 +1,385 @@
+---
+localeCode: zh-CN
+order: 33
+category: 导航类
+title:  Anchor 锚点
+icon: doc-anchor
+brief: 创建超链接导航栏。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Anchor } from '@douyinfe/semi-ui';
+```
+
+### 基本示例
+使用 Link 可以创建锚点,点击它会跳转到指定位置。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor>
+        <Anchor.Link href="#基本示例" title="基本示例" />
+        <Anchor.Link href="#组件" title="组件" />
+        <Anchor.Link href="#设计语言" title="设计语言" />
+        <Anchor.Link href="#物料平台" title="物料平台" />
+        <Anchor.Link href="#主题商店" title="主题商店" />
+    </Anchor>  
+)
+```
+
+### 综合使用
+
+你可以搭配 `getContainer`,`targetOffset`,`style`,`offsetTop` 完成一个拆箱即用的超链接导航栏。
+
+-   滚动容器:你可以通过 `getContainer` 设置滚动内容的容器,默认值为 `window` 。
+
+-   距离顶部的距离:可以通过设置 `targetOffset` 设置文档滚动结束时,锚点距离容器顶部的距离。**v>=1.9**
+
+-   自定义定位方式:Anchor 的默认定位方式为 `relative`,你可以通过 `style` 对象自定义它的定位方式。
+
+-   偏移距离:`offsetTop` 可以在滚动内容距离容器顶部达到指定偏移量时触发当前 Link 切换。
+
+```jsx
+import { Anchor } from '@douyinfe/semi-ui';
+
+() =>  {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <span>请看右侧固定的 Anchor </span>
+            <Anchor
+                getContainer={getContainer}
+                offsetTop={100}
+                targetOffset={100} // v>=1.9
+                style={{ position: 'fixed', right: '20px', top: '100px', width: '200px', zIndex: 3}} >
+                <Anchor.Link href="#基本示例" title="我是固定的 Anchor" />
+                <Anchor.Link href="#综合使用" title="综合使用" />
+                <Anchor.Link href="#尺寸" title="尺寸" />
+                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
+                <Anchor.Link href="#动态展示" title="动态展示" />
+                <Anchor.Link href="#显示工具提示" title="显示工具提示" />
+                <Anchor.Link href="#工具提示位置" title="工具提示位置" />
+                <Anchor.Link href="#API参考" title="API参考">
+                    <Anchor.Link href="#Anchor" title="Anchor" />
+                    <Anchor.Link href="#Anchor.Link" title="Anchor.Link" />
+                </Anchor.Link>
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### 尺寸
+
+Anchor 设置 `size` 可以控制锚点的尺寸。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor size={'default'}>
+        <Anchor.Link href="#组件" title="组件" />
+        <Anchor.Link href="#设计语言" title="设计语言" />
+        <Anchor.Link href="#物料平台" title="物料平台" />
+        <Anchor.Link href="#主题商店" title="主题商店" />
+    </Anchor>
+)
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => (
+    <Anchor size={'small'}>
+        <Anchor.Link href="#组件" title="组件" />
+        <Anchor.Link href="#设计语言" title="设计语言" />
+        <Anchor.Link href="#物料平台" title="物料平台" />
+        <Anchor.Link href="#主题商店" title="主题商店" />
+    </Anchor>
+)
+```
+
+### 滑轨主题
+
+Anchor 设置 `railTheme` 可以控制滑轨的主题色。默认值为 `primary`。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'primary'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}
+            >
+                <Anchor.Link href="#尺寸" title="尺寸" />
+                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
+                <Anchor.Link href="#设计语言" title="设计语言" />
+                <Anchor.Link href="#物料平台" title="物料平台" />
+                <Anchor.Link href="#主题商店" title="主题商店" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'tertiary'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}
+            >
+                <Anchor.Link href="#尺寸" title="尺寸" />
+                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
+                <Anchor.Link href="#设计语言" title="设计语言" />
+                <Anchor.Link href="#物料平台" title="物料平台" />
+                <Anchor.Link href="#主题商店" title="主题商店" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                railTheme={'muted'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}
+            >
+                <Anchor.Link href="#尺寸" title="尺寸" />
+                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
+                <Anchor.Link href="#设计语言" title="设计语言" />
+                <Anchor.Link href="#物料平台" title="物料平台" />
+                <Anchor.Link href="#主题商店" title="主题商店" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### 动态展示
+
+Anchor 设置 `autoCollapse` 可以动态展示下一级锚点。默认值为 `false`。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+        <Anchor
+            autoCollapse={true}
+            getContainer={getContainer}
+            targetOffset={60}
+            offsetTop={100}>
+            <Anchor.Link href="#动态展示" title="1. 动态展示">
+                <Anchor.Link href="#组件" title="1.1 组件">
+                    <Anchor.Link href="#头像" title="1.1.1 Avatar" />
+                    <Anchor.Link href="#按钮" title="1.1.2 Button" />
+                    <Anchor.Link href="#图标" title="1.1.3 Icon" />
+                </Anchor.Link>
+                <Anchor.Link href="#物料" title="1.2 物料" />
+                <Anchor.Link href="#主题商店" title="1.3 主题商店" />
+            </Anchor.Link>
+            <Anchor.Link href="#设计语言" title="2. 设计语言" />
+        </Anchor>
+        </div>
+    )
+}
+```
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+        <Anchor
+            autoCollapse={false}
+            getContainer={getContainer}
+            targetOffset={60}
+            offsetTop={100}>
+            <Anchor.Link href="#动态展示" title="1. 动态展示">
+                <Anchor.Link href="#组件" title="1.1 组件">
+                    <Anchor.Link href="#头像" title="1.1.1 Avatar" />
+                    <Anchor.Link href="#按钮" title="1.1.2 Button" />
+                    <Anchor.Link href="#图标" title="1.1.3 Icon" />
+                </Anchor.Link>
+                <Anchor.Link href="#物料" title="1.2 物料" />
+                <Anchor.Link href="#主题商店" title="1.3 主题商店" />
+            </Anchor.Link>
+            <Anchor.Link href="#设计语言" title="2. 设计语言" />
+        </Anchor>
+        </div>
+    )
+}
+```
+
+### 显示工具提示
+
+Anchor 设置 `showTooltip` 可以在 Link 超出最大宽度时显示 Link 的文字内容。默认值为 `false`。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                showTooltip={true}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}
+            >
+                <Anchor.Link href="#显示工具提示" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
+                <Anchor.Link href="#组件" title="组件" />
+                <Anchor.Link href="#设计语言" title="设计语言" />
+                <Anchor.Link href="#物料平台" title="物料平台" />
+                <Anchor.Link href="#主题商店" title="主题商店" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+### 工具提示位置
+
+Anchor 设置 `position` 可以设置Tooltip的显示位置。它仅在 `showTooltip` 为 `true` 时起作用。
+
+```jsx live=true
+import React from 'react';
+import { Anchor } from '@douyinfe/semi-ui';
+
+() => {
+    const getContainer = () => {
+        return document.querySelector('window');
+    }
+    return (
+        <div>
+            <Anchor
+                showTooltip={true}
+                position={'right'}
+                getContainer={getContainer}
+                targetOffset={60}
+                offsetTop={100}
+            >
+                <Anchor.Link href="#工具提示位置" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
+                <Anchor.Link href="#组件" title="组件" />
+                <Anchor.Link href="#设计语言" title="设计语言" />
+                <Anchor.Link href="#物料平台" title="物料平台" />
+                <Anchor.Link href="#主题商店" title="主题商店" />
+            </Anchor>
+        </div>
+    )
+}
+```
+
+## API 参考
+
+### Anchor
+
+| 属性          | 说明                                             | 类型                                | 默认值    | 版本   |
+| ------------- | ------------------------------------------------ | ----------------------------------- | --------- | - |
+| autoCollapse  | 滚动时动态显示下一级锚点                         | boolean                             | false     |        |
+| className     | 类名                                             | string                              | -         |        |
+| defaultAnchor | 默认高亮锚点                                     | string                              | -         | 1.20.0 |
+| getContainer  | 指定滚动的容器                                   | () => HTMLElement                   | window    |        |
+| maxHeight     | 组件的 max-height,超出时显示滚动条              | string \| number                    | `750px`   |        |
+| maxWidth      | 组件的 max-width,超出时显示...                  | string \| number                    | `200px`   |        |
+| offsetTop     | 滚动内容距离容器顶部达到指定偏移量时触发         | number                              | 0         |        |
+| onChange      | 改变锚点的回调函数                               | (currentLink, previousLink) => void | -         |        |
+| onClick       | 点击锚点回调函数                                 | (event, currentLink) => void        | -         |        |
+| position      | Tooltip 显示位置,可选值同 Tooltip 组件 position | string                              | -         |        |
+| railTheme     | 滑轨主题,可选值:`primary`,`tertiary`,`muted` | string                              | `primary` |        |
+| scrollMotion  | 是否开启滚动动画                                 | boolean                             | false     |        |
+| showTooltip   | 文字缩略时是否显示 Tooltip                       | boolean                             | false     |        |
+| size          | 锚点尺寸,可选值: `small`,`default`            | string                              | `default` |        |
+| style         | 样式对象                                         | object                              | -         |        |
+| targetOffset  | 锚点滚动时距离顶部偏移量                         | number                              | 0         | 1.9.0  |
+
+### Anchor.Link
+
+| 属性      | 说明                 | 类型              | 默认值 |   版本     |
+| --------- | -------------------- | ----------------- | ------ | ------ |
+| className | 类名                 | string            | -      |        |
+| disabled  | 禁用,不响应点击跳转 | boolean           | false  | 1.20.0 |
+| href      | 跳转的链接           | string            | -      |        |
+| style     | 样式对象             | object            | -      |        |
+| title     | 文字内容             | string\|ReactNode | -      |        |
+
+## 设计变量
+<DesignToken/>
+
+## FAQ
+
+1. **为何我的 Link 没有高亮和滑动跟随?**  
+    检查下点击锚点是否可以滚动到指定位置:
+    - 不可以,说明 href 有问题,检查文档中是否存在该 id;
+    - 可以,可能是滚动容器设置不正确,确保文档内容被包裹在滚动容器内。滚动容器默认为 window,如果你的容器是 .my-container 的 div,则应该将滚动容器设置为该 div。
+    
+    ```jsx
+    function() {
+        // 此容器不是 Anchor 组件的容器,是文档内容的容器,因为要根据文档容器去计算当前是哪个 id 在容器上方
+        const getContainer = () => {
+            return document.querySelector('.my-container');
+        }
+        return (
+            <Anchor
+                /* 其他属性 */
+                getContainer={getContainer}
+                >
+                /* Links */
+            </Anchor>
+        )
+    }
+    ```

+ 88 - 0
content/navigation/backtop/index-en-US.md

@@ -0,0 +1,88 @@
+---
+localeCode: en-US
+order: 34
+category: Navigation
+title: BackTop
+subTitle: BackTop
+icon: doc-backtop
+brief: The BackTop component is a button used to return to the top of the page.
+---
+
+## Demos
+
+### How to import
+
+```jsx
+import { BackTop } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+BackTop can be used directly with the default styles.
+
+```jsx live=true
+import React from 'react';
+import { BackTop } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    render() {
+        return (
+            <div>
+                <span>Scroll down to see the bottom-right gray button.</span>
+                <BackTop />
+            </div>
+        );
+    }
+}
+```
+
+### Customized Style
+
+The default styles for BackTop component could be overwritten.
+
+```jsx live=true
+import React from 'react';
+import { BackTop } from '@douyinfe/semi-ui';
+import { IconArrowUp } from '@douyinfe/semi-icons';
+
+class Custom extends React.Component {
+    target() {
+        return document.querySelector('.scroll-wrapper');
+    }
+
+    render() {
+        const style = {
+            height: 30,
+            width: 30,
+            borderRadius: '100%',
+            backgroundColor: '#0077fa',
+            color: '#fff',
+            paddingTop: 5,
+            bottom: 100,
+        };
+
+        return (
+            <div>
+                <span>
+                    Scroll down to see the bottom-right <span style={{ color: '#0077fa' }}>blue circular</span> button.
+                </span>
+                <BackTop style={style}>
+                    <IconArrowUp />
+                </BackTop>
+            </div>
+        );
+    }
+}
+```
+
+## API Reference
+
+| Properties       | Instructions                                                                    | type     | Default      |
+| ---------------- | ------------------------------------------------------------------------------- | -------- | ------------ |
+| className        | Class name                                                                      | string   | -            |
+| duration         | Time used to scroll to the top.                                                 | number   | 450          |
+| style            | Style                                                                           | CSSProperties   | -            |
+| target           | A function that returns the DOM element to add listener to its scrolling event. | () => any | () => window |
+| visibilityHeight | The scrolling heights to be reached in order to show up BackTop.                | number   | 400          |
+| onClick          | The callback to onClick event.                                                  | (e: MouseEvent) => void | -            |
+## Design Tokens
+<DesignToken/>

+ 87 - 0
content/navigation/backtop/index.md

@@ -0,0 +1,87 @@
+---
+localeCode: zh-CN
+order: 34
+category: 导航类
+title: BackTop 回到顶部
+icon: doc-backtop
+brief: 返回页面顶部的操作按钮。
+---
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { BackTop } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+BackTop 预设了基本的返回按钮,可以直接调用。
+
+```jsx live=true
+import React from 'react';
+import { BackTop } from '@douyinfe/semi-ui';
+
+class Demo extends React.Component {
+    render() {
+        return (
+            <div>
+                <span>Scroll down to see the bottom-right gray button.</span>
+                <BackTop />
+            </div>
+        );
+    }
+}
+```
+
+### 自定义样式
+
+BackTop 预设了默认样式,包括:距离底部 50px,距离右侧 100px,`box-sizing` 为 `border-box`,内容水平居中。样式可以覆盖。
+
+```jsx live=true
+import React from 'react';
+import { BackTop } from '@douyinfe/semi-ui';
+import { IconArrowUp } from '@douyinfe/semi-icons';
+
+class Custom extends React.Component {
+    render() {
+        const style = {
+            display: 'flex',
+            alignItems: 'center',
+            justifyContent: 'center',
+            height: 30,
+            width: 30,
+            borderRadius: '100%',
+            backgroundColor: '#0077fa',
+            color: '#fff',
+            bottom: 100,
+        };
+
+        return (
+            <div>
+                <span>
+                    Scroll down to see the bottom-right <span style={{ color: '#0077fa' }}>blue circular</span> button.
+                </span>
+                <BackTop style={style}>
+                    <IconArrowUp />
+                </BackTop>
+            </div>
+        );
+    }
+}
+```
+
+## API 参考
+
+| 属性             | 说明                                                | 类型     | 默认值       |
+| ---------------- | --------------------------------------------------- | -------- | ------------ |
+| className        | 类名                                                | string   | -            |
+| duration         | 滚动到顶部的时间                                    | number   | 450          |
+| style            | 样式名                                              | CSSProperties   | -            |
+| target           | 返回值为需要监听其滚动事件的元素对应 DOM 元素的函数 | () => any | () => window |
+| visibilityHeight | 出现 BackTop 需要达到的滚动高度                     | number   | 400          |
+| onClick          | 点击事件的回调函数                                  | (e: MouseEvent) => void | -            |
+
+## 设计变量
+<DesignToken/>

+ 343 - 0
content/navigation/breadcrumb/index-en-US.md

@@ -0,0 +1,343 @@
+---
+localeCode: en-US
+order: 35
+category: Navigation
+title:  Breadcrumb
+subTitle: Breadcrumb
+icon: doc-breadcrumb
+brief: Breadcrumbs allow users to make selections from a range of values and provide an auxiliary navigation that can return to previous page.
+---
+
+
+## Demos
+
+### How to import
+
+```jsx
+import { Breadcrumb } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+        <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+        <Breadcrumb.Item>Default</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### With Icons
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome, IconArticle } from '@douyinfe/semi-icons';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item icon={<IconHome />}></Breadcrumb.Item>
+        <Breadcrumb.Item icon={<IconArticle />}>Breadcrumb</Breadcrumb.Item>
+        <Breadcrumb.Item>With Icon</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### Size
+
+You can set the `compact` property to `false` to increase the size of icons and texts.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb compact>
+            <Breadcrumb.Item icon={<IconHome />}></Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Loose</Breadcrumb.Item>
+        </Breadcrumb>
+        <br/>
+        <Breadcrumb compact={false}>
+            <Breadcrumb.Item icon={<IconHome />}></Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Loose</Breadcrumb.Item>
+        </Breadcrumb>
+    </div>
+)
+```
+
+### Custom Separator
+
+Default separator is `/`.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconArrowRight } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb separator={'>'}>
+            <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+        <br/>
+        <Breadcrumb separator={<IconArrowRight size={'small'} />}>
+            <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+        <Tag>v>=1.16.0</Tag>
+        <br/>
+        <Breadcrumb size={'small'} >
+            <Breadcrumb.Item separator=":">Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+    </div>
+)
+```
+
+### Truncated Logic
+After **v0.34.0**, the truncation happens if the text is overflowed. Default max-width is set to 150px. You could use `showTooltip` to customize ellipsis behavior.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const routes = ['Home', 'The is a very very very very long title', 'Detail'];
+    const { Text } = Typography;
+    return (
+        <>
+            <Text size="small">Default</Text>
+            <Breadcrumb
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">No tooltip</Text>
+            <Breadcrumb
+                showTooltip={false}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">No truncation</Text>
+            <Breadcrumb
+                showTooltip={{width: 'auto'}}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">Ellipsis from middle of text</Text>
+            <Breadcrumb
+                showTooltip={{ellipsisPos: 'middle'}}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">Customize tooltip</Text>
+            <Breadcrumb
+                showTooltip={{opts: {position: 'topLeft'}}}
+                routes={routes}
+            />
+        </>
+    )
+}
+```
+
+When the path exceeds 4 levels, the second level to the penultimate one will be replaced by ellipsis. You can click the ellipsis to reveal all levels.
+For **v>=1.9.0** , you could use `maxItemCount` to set the number exceeded to trigger auto collapse.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item>Home</Breadcrumb.Item>
+        <Breadcrumb.Item>Many levels</Breadcrumb.Item>
+        <Breadcrumb.Item>Another level</Breadcrumb.Item>
+        <Breadcrumb.Item>Another level again</Breadcrumb.Item>
+        <Breadcrumb.Item>Here is another one</Breadcrumb.Item>
+        <Breadcrumb.Item>Penultimate</Breadcrumb.Item>
+        <Breadcrumb.Item>Detail</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### Custom Ellipsis
+
+There are two ellipsis area rendering types provided inside the component. You can set and select the desired rendering type through `moreType`. The optional values of `moreType` are `default` and `popover`.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb moreType='popover'>
+        <Breadcrumb.Item>Home</Breadcrumb.Item>
+        <Breadcrumb.Item>Many levels</Breadcrumb.Item>
+        <Breadcrumb.Item>Another level</Breadcrumb.Item>
+        <Breadcrumb.Item>Another level again</Breadcrumb.Item>
+        <Breadcrumb.Item>Here is another one</Breadcrumb.Item>
+        <Breadcrumb.Item>Penultimate</Breadcrumb.Item>
+        <Breadcrumb.Item>Detail</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+If you want to customize other forms of rendering for the ellipsis area, you can use the `renderMore()` method.
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb, Popover } from '@douyinfe/semi-ui';
+import { IconMore } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const separator = '-'; // Separator for splicing restItem array items
+    const renderMore = restItem => {
+        const content = (
+            <>
+                {
+                    restItem.map((item, idx) => (
+                        <React.Fragment key={`restItem-${idx}`}>
+                            {item}
+                            {idx !== restItem.length - 1 &&
+                                <span style={{ color: 'var(--semi-color-text-2)', marginRight: '6px' }}>
+                                    {separator}
+                                </span>
+                            }
+                        </React.Fragment>
+                    ))
+                }
+            </>
+        )
+        return (
+            <Popover
+                content={content}
+                style={{ padding: 12 }}
+                showArrow
+            >
+                <IconMore />
+            </Popover>
+        );
+    };
+    return (
+        <>
+            <Breadcrumb
+                renderMore={restItem => renderMore(restItem)}
+                onClick={(item, e) => console.log(item, e)}
+            >
+                <Breadcrumb.Item>Home</Breadcrumb.Item>
+                <Breadcrumb.Item>Many levels</Breadcrumb.Item>
+                <Breadcrumb.Item>Another level</Breadcrumb.Item>
+                <Breadcrumb.Item>Another level again</Breadcrumb.Item>
+                <Breadcrumb.Item>Here is another one</Breadcrumb.Item>
+                <Breadcrumb.Item>Penultimate</Breadcrumb.Item>
+                <Breadcrumb.Item>Detail</Breadcrumb.Item>
+            </Breadcrumb>
+        </>
+    );
+}
+```
+
+### Route Object
+
+Breadcrumb supports passing in an array of strings or route objects consisting of `{ name, path, href, icon }`. You can also use `renderItem` to render React.nodes. Breadcrumbs created in this way will also be truncated.
+
+-   `name`: Name displayed, default with an empty string. When route passed in is a string only, it is set to name property.
+-   `path`: Routing path.
+-   `href`: Link destination and is mounted on the `<a>` tag.
+-   `icon`: Icon displayed.
+ 
+```jsx live=true hideInDSM
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome, IconArticle } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb
+            routes={['Semi-ui', 'Breadcrumb', 'Default']}
+        />
+        <br/>
+        <Breadcrumb
+            routes={
+                [
+                    {
+                        path: '/', 
+                        Href: '/', 
+                        icon: <IconHome />
+                    },
+                    { 
+                        path: '/breadcrumb', 
+                        href: '/components/breadcrumb', 
+                        name: 'breadcrumb', 
+                        icon: <IconArticle />
+                    },
+                    'with icon'
+                ]
+            }
+        />
+        <br/>
+        <Breadcrumb
+            routes={['Index', 'This is a very long level', 'Detail']}
+        />
+    </div>
+)
+```
+
+## API reference
+
+### Breadcrumb
+
+| Properties | Instructions                                                                                      | type                                         | Default   | version |
+| ---------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------- | --------- | ------- |
+| autoCollapse      | Toggle whether to auto collapse when exceed maxItemCount                                                                                     | boolean                                     | true     |    1.9.0   |
+| className  | Class name                                                                                        | string                                       | -         |         |
+| compact    | Compact sizing                                                                                    | boolean                                      | true      |         |
+| maxItemCount      | Set the number of item when reached to collapse                                                                                      | number                                     | 4    | 1.9.0       |
+|moreType|...area rendering type,one of 'default'、'popover'|string|'default'|1.27.0|
+| renderItem | Custom function, used with routes                                                                 | (Route: [Route](#Route)) => React Node               | -         | 0.27.0  |
+|renderMore|Custom ... area rendering|(restItem: ReactNode[]) => ReactNode|-|1.27.0|
+| routes     | Routing information, an array of route objects or strings, format reference: [Route](#Route) | Array<[Route](#Route) \| string\>                              | -         |         |
+| separator  | Customized delimiter                                                                              | string                                       | ReactNode | '/'     |  |
+| showTooltip | Toggle whether to show tooltip if text overflowed. If passed in as an object: width, overflowed width; ellipsisPos, ways of truncation;  opts, passed directly to Tooltip component                              | boolean \| showToolTipProps             | {width: 150, ellipsisPos: 'end', opts: { autoAdjustOverflow: true, position: "bottomLeft" }}      | 0.34.0 |
+| style      | Inline style                                                                                      | CSSProperties                                       | -         |         |
+| onClick    | Click event                                                                                       |  (item: [Route](#Route), e: Event) => void| -         | 0.27.0  |
+
+### Breadcrumb.Item
+
+| Properties | Instructions           | type                             | Default | version |
+| ---------- | ---------------------- | -------------------------------- | ------- | ------- |
+| href       | Destinations for links | string                           | -       |         |
+| icon       | Displayed icon         | ReactNode                           | -       |         |
+| onClick    | Click event            | function (item: Route, e: Event) | -       | 0.27.0  |
+| separator    | Separator, used to override parent separator          | ReactNode | -       | 1.16.0 |
+| noLink    | To remove hover and active effect on an item | boolean | false     | 1.16.0 |
+
+
+### Route
+
+| Properties | Instructions      | type   | Default   | version |
+| ---------- | ----------------- | ------ | --------- | ------- |
+| href       | Link destinations | string | -         | 0.27.0  |
+| icon       | Displayed icon    | ReactNode |  | -       | 
+| name       | Routing name      | string | -         |         |
+| path       | Routing path      | string | -         |         |
+
+After **v>=1.16.0**, other props in Breadcrumb.Item are also supported correspondingly.
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+```material
+87
+``` -->

+ 345 - 0
content/navigation/breadcrumb/index.md

@@ -0,0 +1,345 @@
+---
+localeCode: zh-CN
+order: 35
+category: 导航类
+title:  Breadcrumb 面包屑
+icon: doc-breadcrumb
+brief: 面包屑是用户界面中的一种辅助导航,可以显示当前页面在层级架构中的位置,并能返回之前的页面。
+---
+
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Breadcrumb } from '@douyinfe/semi-ui';
+```
+
+### 基本用法
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+        <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+        <Breadcrumb.Item>Default</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### 带图标的
+
+支持标题只显示图标或者同时显示图标和文本。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome, IconArticle } from '@douyinfe/semi-icons';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item icon={<IconHome size="small" />}></Breadcrumb.Item>
+        <Breadcrumb.Item icon={<IconArticle size="small" />}>Breadcrumb</Breadcrumb.Item>
+        <Breadcrumb.Item>With Icon</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### 尺寸
+
+默认为 `compact`,设置属性为 `false` 可使图标和文字尺寸增加。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb compact>
+            <Breadcrumb.Item icon={<IconHome size="small" />}></Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Loose</Breadcrumb.Item>
+        </Breadcrumb>
+        <br/>
+        <Breadcrumb compact={false}>
+            <Breadcrumb.Item icon={<IconHome size="small" />}></Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Loose</Breadcrumb.Item>
+        </Breadcrumb>
+    </div>
+)
+```
+
+### 自定义的分隔符
+
+默认为 `/`。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconArrowRight } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb separator={'>'}>
+            <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+        <br/>
+        <Breadcrumb separator={<IconArrowRight size={'small'} />}>
+            <Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+        <br/>
+        <Tag>v>=1.16.0</Tag>
+        <br/>
+        <Breadcrumb size={'small'} >
+            <Breadcrumb.Item separator=":">Semi-ui</Breadcrumb.Item>
+            <Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
+            <Breadcrumb.Item>Default</Breadcrumb.Item>
+        </Breadcrumb>
+    </div>
+)
+```
+
+### 截断逻辑
+
+在 **0.34.0** 版本之后,当级别名字溢出设定宽度后省略截断。可以通过 `showTooltip` 属性设置相关参数。默认宽度150px,鼠标悬停时显示 Tooltip 完整显示级别名称。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb, Typography } from '@douyinfe/semi-ui';
+
+() => {
+    const routes = ['首页', '当这个页面标题很长很长很长时需要省略', '详情页'];
+    const { Text } = Typography;
+    return (
+        <>
+            <Text size="small">默认行为</Text>
+            <Breadcrumb
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">省略但不显示Tooltip</Text>
+            <Breadcrumb
+                showTooltip={false}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">不截断</Text>
+            <Breadcrumb
+                showTooltip={{width: 'auto'}}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">从标题中间开始省略</Text>
+            <Breadcrumb
+                showTooltip={{ellipsisPos: 'middle'}}
+                routes={routes}
+            />
+            <br/>
+            <Text size="small">自定义 Tooltip 参数</Text>
+            <Breadcrumb
+                showTooltip={{opts: {position: 'topLeft'}}}
+                routes={routes}
+            />
+        </>
+    )
+}
+```
+
+当路径层级超过 4 个级别,则:第二层至倒数第三层省略,点击省略号展开显示全部级别;如果过长则自动换行。
+在 **v>=1.9.0** 之后,可以通过 `maxItemCount` 来控制超过多少个级别进行折叠。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb>
+        <Breadcrumb.Item>首页</Breadcrumb.Item>
+        <Breadcrumb.Item>当层级很多的时候</Breadcrumb.Item>
+        <Breadcrumb.Item>又一层</Breadcrumb.Item>
+        <Breadcrumb.Item>再一层</Breadcrumb.Item>
+        <Breadcrumb.Item>上上一层</Breadcrumb.Item>
+        <Breadcrumb.Item>上一层</Breadcrumb.Item>
+        <Breadcrumb.Item>详情页</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+### 自定义省略号区域
+
+组件内部提供了两种省略号区域渲染的类型,可通过 `moreType` 来设置,`moreType` 的可选值为 `default` 和 `popover`。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+
+() => (
+    <Breadcrumb moreType='popover'>
+        <Breadcrumb.Item>首页</Breadcrumb.Item>
+        <Breadcrumb.Item>当层级很多的时候</Breadcrumb.Item>
+        <Breadcrumb.Item>又一层</Breadcrumb.Item>
+        <Breadcrumb.Item>再一层</Breadcrumb.Item>
+        <Breadcrumb.Item>上上一层</Breadcrumb.Item>
+        <Breadcrumb.Item>上一层</Breadcrumb.Item>
+        <Breadcrumb.Item>详情页</Breadcrumb.Item>
+    </Breadcrumb>
+)
+```
+
+如果想要为省略号区域自定义其他形式的渲染,则可以使用 `renderMore()` 方法。
+
+```jsx live=true
+import React from 'react';
+import { Breadcrumb, Popover } from '@douyinfe/semi-ui';
+import { IconMore } from '@douyinfe/semi-icons';
+
+function Demo() {
+    const separator = '-'; // 用于拼接 restItem 数组项的分隔符
+    const renderMore = restItem => {
+        const content = (
+            <>
+                {
+                    restItem.map((item, idx) => (
+                        <React.Fragment key={`restItem-${idx}`}>
+                            {item}
+                            {idx !== restItem.length - 1 &&
+                                <span style={{ color: 'var(--semi-color-text-2)', marginRight: '6px' }}>
+                                    {separator}
+                                </span>
+                            }
+                        </React.Fragment>
+                    ))
+                }
+            </>
+        )
+        return (
+            <Popover
+                content={content}
+                style={{ padding: 12 }}
+                showArrow
+            >
+                <IconMore />
+            </Popover>
+        );
+    };
+    return (
+        <>
+            <Breadcrumb
+                renderMore={restItem => renderMore(restItem)}
+                onClick={(item, e) => console.log(item, e)}
+            >
+                <Breadcrumb.Item>首页</Breadcrumb.Item>
+                <Breadcrumb.Item>当层级很多的时候</Breadcrumb.Item>
+                <Breadcrumb.Item>又一层</Breadcrumb.Item>
+                <Breadcrumb.Item>再一层</Breadcrumb.Item>
+                <Breadcrumb.Item>上上一层</Breadcrumb.Item>
+                <Breadcrumb.Item>上一层</Breadcrumb.Item>
+                <Breadcrumb.Item>详情页</Breadcrumb.Item>
+            </Breadcrumb>
+        </>
+    );
+}
+```
+
+### 路由对象
+Breadcrumb 支持通过 routes 传入路由对象 `route: { name, path, href, icon }` 或字符串组成的数组。可以配合 renderItem 来渲染节点。通过这样实现的 Breadcrumb 同样会进行截断处理。
+
+-   name 为展示的名称,不传入时为空字符串。当 route 为字符串时,默认将字符串设置为名称。
+-   path 为路由路径
+-   href 为链接目的地,挂载在 a 标签上。
+-   icon 为标签的显示图标
+
+```jsx live=true hideInDSM
+import React from 'react';
+import { Breadcrumb } from '@douyinfe/semi-ui';
+import { IconHome, IconArticle } from '@douyinfe/semi-icons';
+
+() => (
+    <div>
+        <Breadcrumb
+            routes={['Semi-ui', 'Breadcrumb', 'Default']}
+        />
+        <br />
+        <Breadcrumb
+            routes={
+                [
+                    {
+                        path: '/',
+                        href: '/',
+                        icon: <IconHome size="small" />
+                    },
+                    {
+                        path: '/breadcrumb',
+                        href: '/components/breadcrumb',
+                        name: 'breadcrumb',
+                        icon: <IconArticle size="small" />
+                    },
+                    'with icon'
+                ]
+            }
+        />
+        <br />
+        <Breadcrumb
+            routes={['首页', '当这个页面标题很长时需要省略', '详情页']}
+        />
+    </div>
+)
+```
+
+## API 参考
+
+### Breadcrumb
+
+| 属性       | 说明                                                                                      | 类型                                       | 默认值 | 版本   |
+| ---------- | ----------------------------------------------------------------------------------------- | ------------------------------------------ | ------ | ------ |
+| autoCollapse      | 是否超出maxItemCount后自动折叠                                                                                     | boolean                                     | true     |    1.9.0   |
+| className  | 类名                                                                                      | string                                     | -      |        |
+| compact    | 显示尺寸,是否紧凑                                                                         | boolean                                    | true   |        |
+| maxItemCount      | 超出多少个进行自动折叠                                                                                      | number                                     | 4    | 1.9.0       |
+|moreType|内置的...区域的渲染类型,可选值为 'default'、'popover'|string|'default'|1.27.0|
+| renderItem | 自定义链接函数,配合 routes 使用                                                          | (Route: [Route](#Route)) => ReactNode             | -      | 0.27.0 |
+| renderMore|自定义...区域的渲染|(restItem: ReactNode[]) => ReactNode|-|1.27.0|
+| routes     | router 的路由信息,由路由对象或字符串组成的数组,路由对象格式参考: [Route](#Route) | Array<[Route](#Route) \| string\>                            | -      |        |
+| separator  | 自定义的分隔符                                                                            | ReactNode                          | '/'    |        |
+| showTooltip | 是否展示 Tooltip 及相关配置: width,溢出宽度;   ellipsisPos,截断方式,从中间/末尾截断;                         opts,透传给Tooltip的属性                              | boolean \| showToolTipProps             | {width: 150, ellipsisPos: 'end', opts: { autoAdjustOverflow: true, position: "bottomLeft" }}      | 0.34.0 |
+| style      | 内联样式                                                                                      | CSSProperties                                     | -      |        |
+| onClick    | 单击事件                                                                                  | (item: [Route](#Route) , e: Event) => void | -      | 0.27.0 |
+
+### Breadcrumb.Item
+
+| 属性    | 说明           | 类型                            | 默认值 | 版本   |
+| ------- | -------------- | ------------------------------- | ------ | ------ |
+| href    | 链接的目的地   | string                          | -      |        |
+| icon    | 标签的显示图标 | ReactNode                          | -      |        |
+| onClick | 单击事件       | function(item: Route, e: Event) | -      | 0.27.0 |
+| separator | 分隔符,可以覆盖父级的分隔符     | ReactNode | -      | 1.16.0 |
+| noLink    | 移除 hover 和 active 的样式 | boolean | false      | 1.16.0 |
+
+### Route
+
+| 属性 | 说明           | 类型              | 默认值 | 版本   |
+| ---- | -------------- | ----------------- | ------ | ------ |
+| href | 链接目的地     | string            | -      | 0.27.0 |
+| icon | 标签的显示图标 | ReactNode | -      |        |
+| name | 路由名         | string            | -      |        |
+| path | 路由路径       | string            | -      |        |
+
+**v>=1.16.0** 之后 Route 支持 Breadcrumb.Item 上的相应属性。
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+```material
+87
+``` -->

+ 788 - 0
content/navigation/navigation/index-en-US.md

@@ -0,0 +1,788 @@
+---
+localeCode: en-US
+order: 36
+category: Navigation
+title:  Navigation
+subTitle: Navigation
+icon: doc-navigation
+width: 650px
+dir: column
+brief: A menu list that provides navigation for pages and features.
+---
+
+
+## When to Use
+
+The navigation menu is the soul of a website, and users rely on navigation to jump in various pages. It is generally divided into top navigation and side navigation, top navigation provides global categories and functions, and side navigation provides a multi-level structure to accommodate and arrange the website architecture.
+
+## Demos
+
+### How to import
+
+```jsx
+import { Nav } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+By passing `items` Parameters, you can quickly get a navigation bar.
+
+Each navigation item includes:
+
+-   `itemKey`: The unique identity of the navigation project (must)
+-   `text`: Navigation copywriting
+-   `icon`: Navigation icon
+
+For the meaning of the parameters, see [Nav.Item](#Nav.Item) Or [Nav.Sub](#Nav.Sub)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                Body Style={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                    { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                    {
+                        text: 'Task Platform',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['Task Management', 'User Task Query'],
+                    },
+                ]}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            />
+        );
+    }
+}
+```
+
+### Navigation Indentation
+
+**Version: >= 0.16.0**
+
+> Navigation indentation is currently effective only for first-level navigation.
+
+#### Pure Copywriting Navigation
+
+If the navigation project doesn't come in, `icon` field, then the copy will be automatically filled to the left.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={[ 'task' ]}
+                items={[
+                    { itemKey: 'user', text: 'User Management' },
+                    { itemKey: 'union', text: 'User Center' },
+                    {
+                        itemKey: 'union-management',
+                        text: 'Union Management',
+                        items: ['Announcement Settings', 'Union Inquiries', 'Entry information']
+                    },
+                    {
+                        text: 'Task Platform',
+                        itemKey: 'task',
+                        items: ['Task Management', 'User Task Inquiries'],
+                    },
+                ]}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            />
+        );
+    }
+}
+```
+
+### Define The Head And Bottom
+
+Developers may often define the Logo area and the put away button area, while Navigation provides such a container for developers to quickly define the navigation head and bottom, and you only need to pass in the header or Footer as required.
+
+For `footer`, semi-ui extra encapsulates a pull-up feature button that developers can pass through `collapseButton = true` to turn on the function, but the parameter takes effect only with `mode = "vertical"` (Vertical navigation).
+
+For the parameters, see [Nav.Header](#Nav.Header) and [Nav.Footer](#Nav.Footer).
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                defaultOpenKeys={['task']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                    { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                    {
+                        text: 'Task Platform',
+                        icon: <IconSetting />,
+                        itemKey: 'task',
+                        items: ['Task Management', 'User Task Query'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: 'Live Platform'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### Navigation Style Definition
+
+Navigation currently provides two parameters to define navigation styles:`style` and `bodyStyle`, in which `style` The style used to define the outermost layer of the navigation component, while `bodyStyle` The style used to define the navigation list. (Both the navigation head and the bottom of the navigation accept their respective `style` Parameters).
+
+For example, you need a navigation list to scroll, navigate the head and bottom fixed navigation components, which can be used this way:
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting, IconFolder } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                style={{ height: 520 }}
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={['job', 'resource']}
+                items={[
+                    { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                    { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                    {
+                        text: 'Task Platform',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['Task Management', 'User Task Query'],
+                    },
+                    {
+                        text: 'Resource Management',
+                        icon: <IconFolder />,
+                        itemKey: 'resource',
+                        items: ['Turntable Configuration', 'Turntable Review'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: 'Live Platform'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### JSX Writing
+
+Users can use JSX to define navigation headers, navigation items, and navigation bottoms.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={['user', 'union']}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            >
+                <Nav.Header logo={<img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />} text={'Live Platform'} />
+                <Nav.Item itemKey={'union'} text={'Union Center'} icon={<IconStar />} />
+                <Nav.Sub itemKey={'user'} text="User Management" icon={<IconUser />}>
+                    <Nav.Item itemKey={'golder'} text={'Gold Master Management'} />
+                    <Nav.Item itemKey={'ban'} text={'User Ban'} />
+                </Nav.Sub>
+                <Nav.Sub itemKey={'union-management'} text="Union Management" icon={<IconUserGroup />}>
+                    <Nav.Item itemKey={'notice'} text={'Announcement Settings'} />
+                    <Nav.Item itemKey={'query'} text={'Union Query'} />
+                    <Nav.Item itemKey={'info'} text={'Entry Information'} />
+                </Nav.Sub>
+                <Nav.Footer collapseButton={true} />
+            </Nav>
+        );
+    }
+}
+
+```
+
+### Navigation Direction
+
+Navigation currently offers navigation in two directions:
+
+-   Vertical (default)
+-   Horizontal
+
+You can pass `mode = "vertical"` (default) or `mode = "horizontal"` to control.
+
+In particular, there are some functions (parameters) only in `mode = "vertical"` effective:
+
+-   `isCollapsed` (Navigation put away to the side)
+-   `defaultOpenKeys` | `openKeys` (Specifies the default and controlled array of expanded subnavigation items key, which is valid only in `mode = "vertical"`and `isCollapsed = false`)
+-   `collapseButton` of `Footer`
+
+#### Vertical Direction
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <div style={{ width: '100%' }}>
+                <Nav
+                    bodyStyle={{ height: 320 }}
+                    items={[
+                        { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                        { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                        {
+                            itemKey: 'union-management',
+                            text: 'Union Management',
+                            icon: <IconUserGroup />,
+                            items: ['Announcement Settings', 'Union Query', 'Entry Information']
+                        },
+                        {
+                            text: 'Task Platform',
+                            icon: <IconSetting />,
+                            itemKey: 'job',
+                            items: ['Task Management', 'User Task Query'],
+                        },
+                    ]}
+                    onSelect={key => console.log(key)}
+                    header={{
+                        logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                        text: 'Live Platform'
+                    }}
+                    footer={{
+                        collapseButton: true,
+                    }}
+                />
+            </div>
+        );
+    }
+}
+```
+
+#### Horizontal Direction
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav, Avatar, Dropdown } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting, IconEdit } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <div style={{ width: '100%' }}>
+                <Nav
+                    mode={'horizontal'}
+                    items={[
+                        { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                        { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                        {
+                            itemKey: 'approve-management',
+                            text: 'Approval Management',
+                            icon: <IconEdit />,
+                            items: [
+                                'Check-in Review',
+                                {
+                                    itemKey: 'operation-management',
+                                    text: 'Operations Management',
+                                    items: [
+                                        'Personnel Management',
+                                        'Personnel Change'
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            text: 'Task Platform',
+                            icon: <IconSetting />,
+                            itemKey: 'job',
+                            items: ['Task Management', 'User Task Query'],
+                        },
+                    ]}
+                    onSelect={key => console.log(key)}
+                    header={{
+                        logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                        text: 'Live Platform'
+                    }}
+                    footer={
+                        <Dropdown
+                            position="bottomRight"
+                            render={
+                                <Dropdown.Menu>
+                                    <Dropdown.Item>Detail</Dropdown.Item>
+                                    <Dropdown.Item>Quit</Dropdown.Item>
+                                </Dropdown.Menu>
+                            }
+                        >
+                            <Avatar size="small" color='light-blue' style={{margin: 4}}>BD</Avatar>
+                            <span>Bytedancer</span>
+                        </Dropdown>
+                    }
+                />
+            </div>
+        );
+    }
+}
+```
+
+#### Horizontal Plus Vertical
+
+The general platform design will adopt the mode of horizontal and vertical navigation. Here is a common example.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav, Avatar, Dropdown, Select, Button } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting, IconEdit, IconLanguage } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    constructor() {
+        this.items = [
+            { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+            { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+            {
+                itemKey: 'union-management',
+                text: 'Union Management',
+                icon: <IconUserGroup />,
+                items: ['Announcement Settings', 'Union Query', 'Entry Information']
+            },
+            {
+                itemKey: 'approve-management',
+                text: 'Approval Management',
+                icon: <IconEdit />,
+                items: [
+                    'Check-in Review',
+                    {
+                        itemKey: 'operation-management',
+                        text: 'Operations Management',
+                        items: [
+                            'Personnel Management',
+                            'Personnel Change'
+                        ]
+                    }
+                ]
+            },
+            {
+                text: 'Task Platform',
+                icon: <IconSetting />,
+                itemKey: 'job',
+                items: ['Task Management', 'User Task Query'],
+            },
+        ];
+
+        this.renderHorizontal = this.renderHorizontal.bind(this);
+        this.renderVertical = this.renderVertical.bind(this);
+    }
+
+    renderHorizontal() {
+        return (
+            <Nav
+                mode={'horizontal'}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: 'Live Platform'
+                }}
+                footer={
+                    <>
+                        <Select defaultValue='English' style={{ width: 120, marginRight: 10 }} insetLabel={<IconLanguage />}>
+                            <Select.Option value='Chinese'>中文</Select.Option>
+                            <Select.Option value='English'>English</Select.Option>
+                            <Select.Option value='Korean'>한국어</Select.Option>
+                            <Select.Option value='Japanese'>日本語</Select.Option>
+                        </Select>
+                        <Button style={{ marginRight: 10 }}>Switch to Overseas Version</Button>
+                        <Dropdown
+                            position="bottomRight"
+                            render={
+                                <Dropdown.Menu>
+                                    <Dropdown.Item>Detail</Dropdown.Item>
+                                    <Dropdown.Item>Quit</Dropdown.Item>
+                                </Dropdown.Menu>
+                            }
+                        >
+                            <Avatar size="small" color='light-blue' style={{margin: 4}}>BD</Avatar>
+                            <span>Bytedancer</span>
+                        </Dropdown>
+                    </>
+                }
+            />
+        );
+    }
+
+    renderVertical() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                items={this.items}
+                onSelect={key => console.log(key)}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+
+    render() {
+        return (
+            <>
+            {this.renderHorizontal()}
+            {this.renderVertical()}
+            </>
+        );
+    }
+}
+```
+
+### Expand and collapse arrow position
+
+`toggleIconPosition` set 'left' or 'right', default right
+
+```jsx live=true dir=column
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                toggleIconPosition={'left'}
+                defaultOpenKeys={['job']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    {itemKey:'user', text:'User Management', icon: <IconUser /> },
+                    {itemKey:'union', text:'guild center', icon: <IconStar /> },
+                    {
+                        text:'Task platform',
+                        icon: <IconSetting />,
+                        itemKey:'job',
+                        items: ['task management','user task query'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text:'Live broadcast operation background'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### Indentation limit
+No indentation by default. If you need to indent the navigation items according to the level, please set limitIndent to false
+
+When using Nav.Item to pass navigation items in React Jsx mode, please pass level props to Nav.Item manually.
+
+Object method No need to care about level when passing in navigation items.
+
+limitIndent only takes effect in the vertical direction.
+
+```jsx live=true dir=column
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                limitIndent={false}
+                toggleIconPosition={'left'}
+                defaultOpenKeys={['job']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    {itemKey:'user', text:'User Management', icon: <IconUser /> },
+                    {
+                        text:'Task platform',
+                        icon: <IconSetting />,
+                        itemKey:'job',
+                        items: ['Task Management', {
+                            text:'Task 1',
+                            icon: <IconSetting />,
+                            itemKey:'mission1',
+                            items: ['Task 2',{
+                                text:'Task 3 disassembly',
+                                icon: <IconSetting />,
+                                itemKey:'mission3',
+                                items: ['Subtask 1','Subtask 2'],
+                            }, ],
+                        },],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text:'Live broadcast operation background'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+
+### Uncontrolled Properties
+
+Including:
+
+-   `defaultSelectedKeys` (default selected navigation item `key` array)
+-   `defaultOpenKeys` (default expanded navigation item `key` array, valid only with `mode = "vertical"` and `isCollapsed = false` | `defaultIsCollapsed = false`)
+-   `defaultIsCollapsed` (whether the sidebar is closed by default, valid only when `mode = "vertical"`)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                defaultOpenKeys={['job']}
+                defaultSelectedKeys={['Entry Information']}
+                defaultIsCollapsed={true}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+                    { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+                    {
+                        itemKey: 'union-management',
+                        text: 'Union Management',
+                        icon: <IconUserGroup />,
+                        items: ['Announcement Settings', 'Union Query', 'Entry Information']
+                    },
+                    {
+                        text: 'Task Platform',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['Task Management', 'User Task Query'],
+                    },
+                ]}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: 'Live Platform'
+                }}
+                footer={{
+                    collapseButton: true
+                }}
+            />
+        );
+    }
+}
+
+```
+
+### Controlled Properties
+
+The Navigation component provides several controlled properties that, combined with a variety of callbacks, can easily control navigation.
+
+The properties currently controlled are:
+
+-   `isCollapsed`(whether the sidebar is closed, effective only when `mode="vertical"`)
+-   `selectedKeys` (currently selected navigation item `key` array)
+-   `openKeys` (currently expanded array of navigation items, only `mode="vertical"` and `isCollapsed=false` valid)
+
+The corresponding callback is:
+
+-   `onCollapseChange(isCollapsed: boolean) => void`
+-   `onSelect ({ itemKey: string, selectedKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void`
+-   `onOpenChange ({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void`
+
+```jsx live=true dir="column"
+import React, { useMemo } from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+function NavApp (props = {}) {
+    const [openKeys, setOpenKeys] = useState(['union-management', 'job']);
+    const [selectedKeys, setSelectedKeys] = useState(['User Task Query']);
+    const [isCollapsed, setIsCollapsed] = useState(true);
+
+    const onSelect = data => {
+        console.log('trigger onSelect: ', data);
+        setSelectedKeys([...data.selectedKeys]);
+    };
+    const onOpenChange = data => {
+        console.log('trigger onOpenChange: ', data);
+        setOpenKeys([...data.openKeys]);
+    };
+
+    const onCollapseChange = isCollapsed => {
+        setIsCollapsed(isCollapsed);
+    }
+
+    const items = useMemo(() => [
+        { itemKey: 'user', text: 'User Management', icon: <IconUser /> },
+        { itemKey: 'union', text: 'Union Center', icon: <IconStar /> },
+        {
+            itemKey: 'union-management',
+            text: 'Union Management',
+            icon: <IconUserGroup />,
+            items: ['Announcement Settings', 'Union Query', 'Entry Information']
+        },
+        {
+            text: 'Task Platform',
+            icon: <IconSetting />,
+            itemKey: 'job',
+            items: ['Task Management', 'User Task Query'],
+        },
+    ], []);
+
+    return (
+        <Nav
+            isCollapsed={isCollapsed}
+            openKeys={openKeys}
+            selectedKeys={selectedKeys}
+            bodyStyle={{ height: 360 }}
+            items={items}
+            header={{
+                logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                text: 'Live Platform'
+            }}
+            footer={{
+                collapseButton: true
+            }}
+            onCollapseChange={onCollapseChange}
+            onOpenChange={onOpenChange}
+            onSelect={onSelect}
+        />
+    )
+}
+```
+
+## API Reference
+
+### Nav
+
+| Properties          | Type                                                                                                                                                                                       | Description                                                                                                                      | Default    |
+| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| bodyStyle           | Custom style for navigation item list                                                                                                                                                      | object                                                                                                                           |            |
+| className           | Style name of outermost element                                                                                                                                                            | boolean                                                                                                                          |            |
+| defaultIsCollapsed  | Whether the default is put away, valid only when `mode = "vertical"`                                                                                                                       | boolean                                                                                                                          | false      |
+| defaultOpenKeys     | Initially open sub navigation `itemKey` array, valid only `mode = "vertical"`and the sidebar is in an expanded state                                                                       | string[]                                                                                                                         | []         |
+| defaultSelectedKeys | Originally selected navigation item `itemKey` array                                                                                                                                        | string[]                                                                                                                         | []         |
+| footer              | The bottom area configure objects or elements, see [Nav.Footer](#Nav.Footer)                                                                                                               | object\|ReactNode                                                                                                                |            |
+| header              | Head area configuration objects or elements, see [Nav.Header](#Nav.Header)                                                                                                                 | object\|ReactNode                                                                                                                |            |
+| isCollapsed         | A controlled attribute of whether it is in a put-away state, valid only when `mode = "vertical"`                                                                                           | boolean                                                                                                                          |            |
+| items               | Navigate the list of items, each item can continue with the items property. If it is a string array, each item is taken as text and itemKey                                                | object\|string[]\|[Item](#Nav.Item)[]\|[Sub](#Nav.Sub)[]                                                                         |            |
+| mode                | Navigation type, currently supports horizontal and vertical, optional value: `vertical`\|`horizontal`                                                                                      | string                                                                                                                           | `vertical` |
+| onClick             | Trigger when clicking on any navigation item                                                                                                                                               | ({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => void                                                             | () = > {}  |
+| onCollapseChange    | The callback when the state changes.                                                                                                                                                       | (is Collapsed: boolean) => void                                                                                                  | () = > {}  |
+| onOpenChange        | Triggers when switching the hidden state of a sub navigation project                                                                                                                       | ({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void                                         | () = > {}  |
+| onSelect            | Triggers the first time you select an optional navigation project, where the selected Items field version > = 0.17.0 is supported                                                          | ({ itemKey: string, selectedKeys: string[], selectedItems: [Item](#Nav.Item)[], domEvent: MouseEvent, isOpen: boolean }) => void | () = > {}  |
+| openKeys            | Controlled open sub navigation `itemKey` array, expanded with `onOpenChange` callback control sub navigation items, valid only `mode = "vertical"`and the sidebar is in an unfolding state | string[]                                                                                                                         |            |
+| selectedKeys        | Controlled navigation item `itemKey` array, with `onSelect` callback control navigation item selection                                                                                     | string[]                                                                                                                         |            |
+| style               | Custom styles for outermost elements                                                                                                                                                       | object                                                                                                                           |            |
+| subNavCloseDelay    | Delay of sub navigation floating layer closure. Effective when the limit is true or mode is "limit" in MS                                                                                  | number                                                                                                                           | 100        |
+| subNavOpenDelay     | The delay displayed by the sub navigation floating layer. Effective when the input is true or mode is "selected" in MS                                                                     | number                                                                                                                           | 0          |
+| tooltipHideDelay    | The latency hidden by tooltip is valid when it is true in MS                                                                                                                               | number                                                                                                                           | 100        |
+| tooltipShowDelay    | The delay displayed by tooltip is valid when it is true in MS                                                                                                                              | number                                                                                                                           | 0          |
+| limitIndent         | To lift the indentation limit, you can use level to customize the indentation of navigation items. The horizontal mode can only be true >=1.27.0                                           | boolean                                                                                                                          | true       |
+| toggleIconPosition  | Parent navigation item arrow position with child navigation items >=1.27.0                                                                                                                 | 'left' \| 'right'                                                                                                                | 'right'    |
+
+### Nav.Item
+
+| Properties   | Description                                                                                                       | Type                                                                 | Default  | Version |
+| ------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------- | ------- |
+| disabled     | Disabled state                                                                                                    | boolean                                                              | false    | 1.17.0  |
+| icon         | Navigation project icon name or component                                                                         | ReactNode                                                            |          |         |
+| indent       | If the icon is empty, keep its space or not. Only effective for first level navigation                            | boolean                                                              | false    |         |
+| itemKey      | Navigation project only key                                                                                       | string                                                               | ""       |         |
+| level        | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number                                                               | 1.27.0   |
+| link         | Navigation item href link, when imported, the navigation item will be wrapped with an a tag                       | string                                                               | -        | 1.0.0   |
+| linkOptions  | Parameters transparently passed to the a tag                                                                      | object                                                               | -        | 1.0.0   |
+| text         | Navigation project copy or element                                                                                | string \| ReactNode                                                  | ""       |         |
+| onClick      | Callback of click                                                                                                 | function({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) | () => {} |
+| onMouseEnter | Callback of mouse enter event                                                                                     | function(e) => {}                                                    | () => {} |
+| onMouseLeave | Callback of mouse leave event                                                                                     | function(e) => {}                                                    | () => {} |
+
+### Nav.Sub
+
+| Properties    | Description                                                                                                       | Type                | Default  |
+| ------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------- | -------- |
+| disabled      | Disabled state                                                                                                    | boolean             | false    | 1.17.0 |
+| dropdownStyle | Style of dropdown layer                                                                                           | CSSProperties       |          |        |
+| icon          | Navigation project icon name or component                                                                         | ReactNode           |          |
+| indent        | If the icon is empty, keep its space or not. Only effective for first level navigation                            | boolean             | false    |
+| isCollapsed   | Whether it is a controlled attribute in the collapsed state, only `mode = "vertical"`                             | boolean             | false    |
+| isOpen        | Control open state                                                                                                | boolean             | false    |
+| itemKey       | Navigation project only key                                                                                       | string              | ""       |
+| level         | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number              | 1.27.0   |
+| maxHeight     | max height                                                                                                        | number              | 999      |
+| text          | Navigation project copy or component                                                                              | string \| ReactNode | ""       |
+| onMouseEnter  | Callback of mouse enter event                                                                                     | function(e) => {}   | () => {} |
+| onMouseLeave  | Callback of mouse leave event                                                                                     | function(e) => {}   | () => {} |
+
+### Nav.Header
+
+| Properties  | Description                                                                                 | Type                | Default | Version |
+| ----------- | ------------------------------------------------------------------------------------------- | ------------------- | ------- | ------- |
+| children    | Sub element                                                                                 | ReactNode           |         |         |
+| className   | Outermost style name                                                                        | string              |         |         |
+| link        | Navigation item href link, when imported, the navigation item will be wrapped with an a tag | string              | -       | 1.0.0   |
+| linkOptions | Parameters transparently passed to the a tag                                                | object              | -       | 1.0.0   |
+| logo        | Logo, can be a string or component                                                          | string \| ReactNode |         |         |
+| style       | Outermost style                                                                             | object              |         |         |
+| text        | Logo copy, which can be a string or component                                               | string \| ReactNode |         |         |
+
+### Nav.Footer
+
+| Properties     | Description                                                                                                                       | Type                                      | Default | Version |
+| -------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------- | ------- |
+| children       | Sub element                                                                                                                       | ReactNode                                 |         |         |
+| className      | Outermost style name                                                                                                              | string                                    |         |         |
+| collapseButton | Do you show the bottom "put away the sidebar" button, mode = "vertical" and the child parameter of the Footer component is empty? | boolean\|ReactNode                        | false   |         |
+| collapseText   | Title of the collapse button                                                                                                      | (collapsed?:boolean) => string\|ReactNode |         | 0.35.0  |
+| style          | Outermost style                                                                                                                   | object                                    |         |         |
+
+## Design Tokens
+<DesignToken/>
+
+<!-- ## Related Material
+```material
+2, 43, 312
+``` -->
+
+## FAQ
+- **Lost animation in navigation bar?**
+
+    When using functional components, you should give items with useState or useMemo, because passing an array directly to items will trigger component re rendering.

+ 791 - 0
content/navigation/navigation/index.md

@@ -0,0 +1,791 @@
+---
+localeCode: zh-CN
+order: 36
+category: 导航类
+title:  Navigation 导航
+icon: doc-navigation
+width: 650px
+dir: column
+brief: 为页面和功能提供导航的菜单列表。
+---
+
+
+## 何时使用
+
+导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转。一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。
+
+## 代码演示
+
+### 如何引入
+
+```jsx import
+import { Nav } from '@douyinfe/semi-ui';
+```
+
+### 基本使用
+
+通过传递 `items` 参数,你能够快速得到一个导航栏。
+
+每个导航项目包括:
+
+-   `itemKey`:导航项目的唯一标识(必须)
+-   `text`:导航文案
+-   `icon`:导航图标
+
+参数含义详见 [Nav.Item](#Nav.Item) 或 [Nav.Sub](#Nav.Sub)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                    { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            />
+        );
+    }
+}
+
+```
+
+### 导航缩进
+
+版本:>= 0.16.0
+
+> 导航缩进目前仅对第一级导航有效果。
+
+#### 纯文案导航
+
+如果导航项目没有传入 `icon` 字段,那么文案会自动向左填充。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={[ 'job' ]}
+                items={[
+                    { itemKey: 'user', text: '用户管理' },
+                    { itemKey: 'union', text: '公会中心' },
+                    {
+                        itemKey: 'union-management',
+                        text: '公会管理',
+                        items: ['公告设置', '公会查询', '信息录入']
+                    },
+                    {
+                        text: '任务平台',
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            />
+        );
+    }
+}
+```
+
+### 定义头部和底部
+
+开发者可能会经常定义 Logo 区域和收起按钮区域,Navigation 则提供了这样的容器方便开发者快速定义导航头部和底部,你仅需按要求传入 header 或 footer 即可。
+
+对于 `footer`,semi-ui 额外封装了一个收起功能按钮,开发者可以通过传递 `collapseButton = true` 开启此功能,不过该参数仅在 `mode = "vertical"` (垂直导航)生效。
+
+参数详见[Nav.Header](#Nav.Header)和[Nav.Footer](#Nav.Footer)。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                defaultOpenKeys={['job']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                    { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### 导航样式定义
+
+Navigation 目前提供了个两个参数用于定义导航样式:`style` 和 `bodyStyle`,其中 `style` 用于定义导航组件最外层的样式,而 `bodyStyle` 用于定义导航列表的样式。(导航头部和导航底部则都接受各自的 `style` 参数)。
+
+例如你需要一个导航列表可以滚动,导航头部和底部固定的导航组件,可以这么使用:
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting, IconFolder } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                style={{ height: 520 }}
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={['job', 'resource']}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                    { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                    {
+                        text: '资源管理',
+                        icon: <IconFolder />,
+                        itemKey: 'resource',
+                        items: ['转盘配置', '转盘审核'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### JSX 写法
+
+用户可以使用 JSX 写法定义导航头部、导航项以及导航底部。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                defaultOpenKeys={['user', 'union']}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+            >
+                <Nav.Header logo={<img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />} text={'直播运营后台'} />
+                <Nav.Item itemKey={'union'} text={'公会中心'} icon={<IconStar />} />
+                <Nav.Sub itemKey={'user'} text="用户管理" icon={<IconUser />}>
+                    <Nav.Item itemKey={'golder'} text={'金主管理'} />
+                    <Nav.Item itemKey={'ban'} text={'用户封禁'} />
+                </Nav.Sub>
+                <Nav.Sub itemKey={'union-management'} text="公会管理" icon={<IconUserGroup />}>
+                    <Nav.Item itemKey={'notice'} text={'公告设置'} />
+                    <Nav.Item itemKey={'query'} text={'公会查询'} />
+                    <Nav.Item itemKey={'info'} text={'信息录入'} />
+                </Nav.Sub>
+                <Nav.Footer collapseButton={true} />
+            </Nav>
+        );
+    }
+}
+
+```
+
+### 导航方向
+
+Navigation 目前提供两种方向的导航:
+
+-   垂直方向(默认)
+-   水平方向
+
+你可以通过 `mode = "vertical"` (默认)或者 `mode = "horizontal"` 来控制。
+
+特别注意的是,有一些功能(参数)仅在 `mode = "vertical"` 时有效:
+
+-   `isCollapsed` (导航收起到侧边)
+-   `defaultOpenKeys` | `openKeys` (指定默认的以及受控的展开子导航项 key 数组,这个参数仅在 `mode = "vertical"` 且 `isCollapsed = false` 有效)
+-   `Footer` 组件的 `collapseButton` 收起侧边栏功能按钮
+
+#### 竖直方向
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <div style={{ width: '100%' }}>
+                <Nav
+                    bodyStyle={{ height: 320 }}
+                    items={[
+                        { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                        { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                        {
+                            itemKey: 'union-management',
+                            text: '公会管理',
+                            icon: <IconUserGroup />,
+                            items: ['公告设置', '公会查询', '信息录入']
+                        },
+                        {
+                            text: '任务平台',
+                            icon: <IconSetting />,
+                            itemKey: 'job',
+                            items: ['任务管理', '用户任务查询'],
+                        },
+                    ]}
+                    onSelect={key => console.log(key)}
+                    header={{
+                        logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                        text: '直播运营后台'
+                    }}
+                    footer={{
+                        collapseButton: true,
+                    }}
+                />
+            </div>
+        );
+    }
+}
+```
+
+#### 水平方向
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav, Avatar, Dropdown } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting, IconEdit } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <div style={{ width: '100%' }}>
+                <Nav
+                    mode={'horizontal'}
+                    items={[
+                        { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                        { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                        {
+                            itemKey: 'approve-management',
+                            text: '审批管理',
+                            icon: <IconEdit />,
+                            items: [
+                                '入驻审核',
+                                {
+                                    itemKey: 'operation-management',
+                                    text: '运营管理',
+                                    items: [
+                                        '人员管理',
+                                        '人员变更'
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            text: '任务平台',
+                            icon: <IconSetting />,
+                            itemKey: 'job',
+                            items: ['任务管理', '用户任务查询'],
+                        },
+                    ]}
+                    onSelect={key => console.log(key)}
+                    header={{
+                        logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                        text: '直播运营后台'
+                    }}
+                    footer={
+                        <Dropdown
+                            position="bottomRight"
+                            render={
+                                <Dropdown.Menu>
+                                    <Dropdown.Item>详情</Dropdown.Item>
+                                    <Dropdown.Item>退出</Dropdown.Item>
+                                </Dropdown.Menu>
+                            }
+                        >
+                            <Avatar size="small" color='light-blue' style={{margin: 4}}>BD</Avatar>
+                            <span>Bytedancer</span>
+                        </Dropdown>
+                    }
+                />
+            </div>
+        );
+    }
+}
+```
+
+#### 水平加垂直
+
+一般的平台设计会采取水平加垂直导航的模式,这里有一个比较常见的例子。
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav, Avatar, Dropdown, Select, Button } from '@douyinfe/semi-ui';
+import { IconStar, IconUser, IconUserGroup, IconSetting, IconEdit, IconLanguage } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    constructor() {
+        this.items = [
+            { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+            { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+            {
+                itemKey: 'union-management',
+                text: '公会管理',
+                icon: <IconUserGroup />,
+                items: ['公告设置', '公会查询', '信息录入']
+            },
+            {
+                itemKey: 'approve-management',
+                text: '审批管理',
+                icon: <IconEdit />,
+                items: [
+                    '入驻审核',
+                    {
+                        itemKey: 'operation-management',
+                        text: '运营管理',
+                        items: [
+                            '人员管理',
+                            '人员变更'
+                        ]
+                    }
+                ]
+            },
+            {
+                text: '任务平台',
+                icon: <IconSetting />,
+                itemKey: 'job',
+                items: ['任务管理', '用户任务查询'],
+            },
+        ];
+
+        this.renderHorizontal = this.renderHorizontal.bind(this);
+        this.renderVertical = this.renderVertical.bind(this);
+    }
+
+    renderHorizontal() {
+        return (
+            <Nav
+                mode={'horizontal'}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={
+                    <>
+                        <Select defaultValue='Chinese' style={{ width: 120, marginRight: 10 }} insetLabel={<IconLanguage />}>
+                            <Select.Option value='Chinese'>中文</Select.Option>
+                            <Select.Option value='English'>English</Select.Option>
+                            <Select.Option value='Korean'>한국어</Select.Option>
+                            <Select.Option value='Japanese'>日本語</Select.Option>
+                        </Select>
+                        <Button style={{ marginRight: 10 }}>切换至海外版</Button>
+                        <Dropdown
+                            position="bottomRight"
+                            render={
+                                <Dropdown.Menu>
+                                    <Dropdown.Item>详情</Dropdown.Item>
+                                    <Dropdown.Item>退出</Dropdown.Item>
+                                </Dropdown.Menu>
+                            }
+                        >
+                            <Avatar size="small" color='light-blue' style={{margin: 4}}>BD</Avatar>
+                            <span>Bytedancer</span>
+                        </Dropdown>
+                    </>
+                }
+            />
+        );
+    }
+
+    renderVertical() {
+        return (
+            <Nav
+                bodyStyle={{ height: 320 }}
+                items={this.items}
+                onSelect={key => console.log(key)}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+
+    render() {
+        return (
+            <>
+            {this.renderHorizontal()}
+            {this.renderVertical()}
+            </>
+        );
+    }
+}
+```
+
+### 展开收起箭头位置
+
+`toggleIconPosition` 设置 'left' 或 'right', 默认 right
+
+```jsx live=true dir=column
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                toggleIconPosition={'left'}
+                defaultOpenKeys={['job']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                    { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+### 缩进限制
+默认无缩进,需要导航项依据层级缩进请将 limitIndent 设置为 false
+
+React Jsx 方式用 Nav.Item 传入导航项时 请手动给 Nav.Item 传入 `level` props。
+
+Object 方式 传入导航项时 无需关心 level
+
+limitIndent 只在 竖直方向生效
+
+```jsx live=true dir=column
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                limitIndent={false}
+                toggleIconPosition={'left'}
+                defaultOpenKeys={['job']}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: 'user' },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', {
+                            text: '任务1',
+                            icon: <IconSetting />,
+                            itemKey: 'mission1',
+                            items: ['任务2',{
+                                text: '任务3拆解',
+                                icon: <IconSetting />,
+                                itemKey: 'mission3',
+                                items: ['子任务1', '子任务2'],
+                            }, ],
+                        },],
+                    },
+                ]}
+                onSelect={key => console.log(key)}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+    }
+}
+```
+
+
+### 非受控属性
+
+包括:
+
+-   `defaultSelectedKeys`(默认被选中的导航项 `key` 数组)
+-   `defaultOpenKeys`(默认展开的导航项 `key` 数组,仅 `mode = "vertical"` 且 `isCollapsed` | `defaultIsCollapsed = false` 的情况下有效)
+-   `defaultIsCollapsed`(侧边栏默认是否收起,仅 `mode = "vertical"` 时有效)
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+class NavApp extends React.Component {
+    render() {
+        return (
+            <Nav
+                defaultOpenKeys={['job']}
+                defaultSelectedKeys={['信息录入']}
+                defaultIsCollapsed={true}
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+                    { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+                    {
+                        itemKey: 'union-management',
+                        text: '公会管理',
+                        icon: <IconUserGroup />,
+                        items: ['公告设置', '公会查询', '信息录入']
+                    },
+                    {
+                        text: '任务平台',
+                        icon: <IconSetting />,
+                        itemKey: 'job',
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                header={{
+                    logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                    text: '直播运营后台'
+                }}
+                footer={{
+                    collapseButton: true
+                }}
+            />
+        );
+    }
+}
+
+```
+
+### 受控属性
+
+Navigation 组件提供了几个受控属性,配合各种回调,可以很轻松地控制导航。
+
+目前受控的属性为:
+
+-   `isCollapsed`(侧边栏是否收起,仅 `mode =" vertical"` 时生效)
+-   `selectedKeys`(当前选中的导航项 `key` 数组)
+-   `openKeys` (当前展开的导航项数组,仅 `mode = "vertical"` 且 `isCollapsed = false` 有效)
+
+对应的回调为:
+
+-   `onCollapseChange(isCollapsed: boolean): void`
+-   `onSelect({ itemKey: string, selectedKeys: string[], domEvent: MouseEvent, isOpen: boolean }): void`
+-   `onOpenChange({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }): void`
+
+```jsx live=true dir="column"
+import React, { useMemo, useState } from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconUserGroup, IconSetting } from '@douyinfe/semi-icons';
+
+function NavApp (props = {}) {
+    const [openKeys, setOpenKeys] = useState(['union-management', 'job']);
+    const [selectedKeys, setSelectedKeys] = useState(['用户任务查询']);
+    const [isCollapsed, setIsCollapsed] = useState(true);
+
+    const onSelect = data => {
+        console.log('trigger onSelect: ', data);
+        setSelectedKeys([...data.selectedKeys]);
+    };
+    const onOpenChange = data => {
+        console.log('trigger onOpenChange: ', data);
+        setOpenKeys([...data.openKeys]);
+    };
+
+    const onCollapseChange = isCollapsed => {
+        setIsCollapsed(isCollapsed);
+    }
+
+    const items = useMemo(() => [
+        { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
+        { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+        {
+            itemKey: 'union-management',
+            text: '公会管理',
+            icon: <IconUserGroup />,
+            items: ['公告设置', '公会查询', '信息录入']
+        },
+        {
+            text: '任务平台',
+            icon: <IconSetting />,
+            itemKey: 'job',
+            items: ['任务管理', '用户任务查询'],
+        },
+    ], []);
+
+    return (
+        <Nav
+            isCollapsed={isCollapsed}
+            openKeys={openKeys}
+            selectedKeys={selectedKeys}
+            bodyStyle={{ height: 360 }}
+            items={items}
+            header={{
+                logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
+                text: '直播运营后台'
+            }}
+            footer={{
+                collapseButton: true
+            }}
+            onCollapseChange={onCollapseChange}
+            onOpenChange={onOpenChange}
+            onSelect={onSelect}
+        />
+    )
+}
+```
+
+## API 参考
+
+### Nav
+
+| 属性                | 类型                                                                                                                             | 描述                                                                                                                           | 默认值     |
+| ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------- |
+| bodyStyle           | 导航项列表的自定义样式                                                                             | object                                                                                                                           |           |
+| className           | 最外层元素的样式名                                                                               | boolean                                                                                                                          |           |
+| defaultIsCollapsed  | 默认是否处于收起状态,仅 `mode = "vertical"` 时有效                                                    | boolean                                                                                                                          | false     |
+| defaultOpenKeys     | 初始打开的子导航 `itemKey` 数组,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效                               | string[]                                                                                                                         | []        |
+| defaultSelectedKeys | 初始选中的导航项 `itemKey` 数组                                                                   | string[]                                                                                                                         | []        |
+| footer              | 底部区域配置对象或元素,详见 [Nav.Footer](#Nav.Footer)                                                | object\| ReactNode |                      |
+| header              | 头部区域配置对象或元素,详见 [Nav.Header](#Nav.Header)                                                | object\| ReactNode |                      |
+| isCollapsed         | 是否处于收起状态的受控属性,仅 `mode = "vertical"` 时有效                                                 | boolean                                                                                                                          |           |
+| items               | 导航项目列表,每一项可以继续带有 items 属性。如果为 string 数组,则会取每一项作为 text 和 itemKey                         | object\| string[] \| [Item](#Nav.Item)[] \| [Sub](#Nav.Sub)[] |  |
+| limitIndent         | 解除缩进限制,可使用 level 自定义导航项缩进,水平模式只能为true >=1.27.0                                          | boolean                                                                                                                          | true      |
+| mode                | 导航类型,目前支持横向与竖直,可选值:`vertical`\                                                          | `horizontal`                                                                                                                     | string    | `vertical`           |
+| openKeys            | 受控的打开的子导航 `itemKey` 数组,配合 `onOpenChange` 回调控制子导航项展开,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效 | string[]                                                                                                                         |           |
+| prefixCls           | 类名前缀                                                                                    | string                                                                                                                           | `semi`    |
+| selectedKeys        | 受控的导航项 `itemKey` 数组,配合 `onSelect` 回调控制导航项选择                                             | string[]                                                                                                                         |           |
+| style               | 最外层元素的自定义样式                                                                             |         CSSProperties                                                                                                                         |           |
+| subNavCloseDelay    | 子导航浮层关闭的延迟。collapse 为 true 或 mode 为 "horizontal" 时有效,单位为 ms                             | number                                                                                                                           | 100       |
+| subNavMotion        | 子导航折叠动画                                                                                 | boolean                                                                                                                          | true      |
+| subNavOpenDelay     | 子导航浮层显示的延迟。collapse 为 true 或 mode 为 "horizontal" 时有效,单位为 ms                             | number                                                                                                                           | 0         |
+| toggleIconPosition  | 带有子导航项的的父级导航项箭头位置 >=1.27.0                                                              | 'left' \| 'right'   | 'right'              |
+| tooltipHideDelay    | tooltip 隐藏的延迟,collapse 为 true 时有效,单位为 ms                                                | number                                                                                                                           | 100       |
+| tooltipShowDelay    | tooltip 显示的延迟,collapse 为 true 时有效,单位为 ms                                                | number                                                                                                                           | 0         |
+| onClick             | 点击任意导航项时触发                                                                              | ({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => {}                                                               | () => {}  |
+| onCollapseChange    | 收起状态变化时的回调                                                                              | (isCollapsed: boolean) => {}                                                                                                     | () => {}  |
+| onOpenChange        | 切换某个子导航项目显隐状态时触发                                                                        | ({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => {}                                           | () => {}  |
+| onSelect            | 第一次选中某个可选中导航项目时触发,其中 selectedItems 这个字段版本 >= 0.17.0 后才支持 | ({ itemKey: string, selectedKeys: string[], selectedItems: [Item](#Nav.Item)[], domEvent: MouseEvent, isOpen: boolean }) => {} | () => {}  |
+
+### Nav.Item
+
+| 属性        | 描述                                               | 类型              | 默认值 | 版本          |
+|-------------|--------------------------------------------------|-------------------|--------|---------------|
+| disabled    | 是否禁用                                           | boolean | false     | 1.17.0              |
+| icon        | 导航项目图标                             | ReactNode |      |               |
+| indent      | 如果 icon 为空,是否保留其占位,仅对一级导航生效       | boolean           | false  |               |
+| itemKey     | 导航项目唯一 key                                   | string            | ""     |               |
+| level       | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置| number | 1.27.0 |
+| link        | 导航项 href 链接,传入时导航项整体会包裹一个 a 标签 | string            | -      | 1.0.0 |
+| linkOptions | 透传给 a 标签的参数                                | object            | -      | 1.0.0 |
+| text        | 导航项目文案或元素                                 | string\|ReactNode | ""     |               |
+| onClick     | 点击任意导航项时触发 |function({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) |  () => {}   | 
+| onMouseEnter| mouse enter 时触发 |function(e) => {} | () => {}   | 
+| onMouseLeave| mouse leave 时触发 |function(e) => {} | () => {}   | 
+
+### Nav.Sub
+
+| 属性    | 描述                           | 类型              | 默认值 |
+| ------- | ------------------------------ | ----------------- | ------ |
+| disabled    | 是否禁用                                           | boolean | false     | 1.17.0             |
+| dropdownStyle | 弹出层的 style                                           | CSSProperties |     |              |
+| icon    | 导航项目图标       | ReactNode |      |
+| indent  | 如果 icon 为空,是否保留其占位,仅对一级导航生效 | boolean           | false  |
+| isCollapsed         |  是否处于收起状态的受控属性,仅 `mode = "vertical"`      | boolean  |    false        |
+| isOpen         |  是否打开      | boolean  |    false        |
+| itemKey | 导航项目唯一 key               | string            | ""     |
+| level       | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置| number | 0 | 1.27.0 |
+| maxHeight       | 最大高度 | number | 999 |
+| text    | 导航项目文案或组件             | string\|ReactNode | ""     |
+| onMouseEnter| mouse enter 时触发 |function(e) => {} | () => {}   | 
+| onMouseLeave| mouse leave 时触发 |function(e) => {} | () => {}   | 
+
+### Nav.Header
+
+| 属性        | 描述                                               | 类型              | 默认值 | 版本          |
+|-------------|--------------------------------------------------|-------------------|--------|---------------|
+| children    | 子元素                                             | ReactNode         |        |               |
+| className   | 最外层样式名                                       | string            |        |               |
+| link        | 导航向 href 链接,传入时导航项整体会包裹一个 a 标签 | string            | -      | 1.0.0 |
+| linkOptions | 透传给 a 标签的参数                                | object            | -      | 1.0.0 |
+| logo        | Logo                         | ReactNode |        |               |
+| style       | 最外层样式                                         | CSSProperties            |        |               |
+| text        | Logo 文案                       | ReactNode |        |               |
+
+### Nav.Footer
+
+| 属性           | 描述                                                                                     | 类型                                      | 默认值 | 版本           |
+| -------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------- | ------ | -------------- |
+| children       | 子元素                                                                                   | ReactNode                                 |        |                |
+| className      | 最外层样式名                                                                             | string                                    |        |                |
+| collapseButton | 是否展示底部“收起侧边栏”按钮,mode="vertical" 且 Footer 组件的 children 参数为空才有效果 | boolean\|ReactNode                        | false  |                |
+| collapseText   | “收起”按钮的文案                                                                         | (collapsed?:boolean) => string\|ReactNode |        | 0.35.0 |
+| style          | 最外层样式                                                                               | CSSProperties                                    |        |                |
+
+## 设计变量
+<DesignToken/>
+
+<!-- ## 相关物料
+```material
+2, 43, 312
+``` -->
+
+## FAQ
+
+-   **导航动画丢失?**  
+    在使用函数式组件时,应该用 useState 或者 useMemo 包裹一下 items,原因是 items 直接传一个数组会触发组件重新渲染。

+ 210 - 0
content/navigation/pagination/index-en-US.md

@@ -0,0 +1,210 @@
+---
+localeCode: en-US
+order: 37
+category: Navigation
+title:  Pagination
+subTitle: Pagination
+icon: doc-pagination
+width: 45%
+brief: The Pager helps users navigate between multiple pages
+---
+
+## Demos
+
+### How to import
+
+```jsx
+import { Pagination } from '@douyinfe/semi-ui';
+```
+### Basic Usage
+
+Set the total number of pages via `Total`, Set capacity per page via `pageSize`.
+
+```jsx live=true width=55%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination total={30} style={{ marginBottom: 12 }}></Pagination>
+        <Pagination total={80} style={{ marginBottom: 12 }}></Pagination>
+        <Pagination total={200} style={{ marginBottom: 12 }}></Pagination>
+        <Pagination total={80} pageSize={30} style={{ marginBottom: 12 }}></Pagination>
+    </div>
+)
+```
+
+### Show total page number
+
+Use the showTotal property to control whether the total number of pages is shown.
+
+```jsx live=true width=55%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination total={80} showTotal style={{ marginBottom: 12 }}></Pagination>
+        <Pagination total={200} showTotal style={{ marginBottom: 12 }}></Pagination>
+    </div>
+)
+```
+
+### Specify current page number
+
+You can specify the currently active page number via `defaultCurrentPage`.
+
+```jsx live=true width=55%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination total={80} showTotal defaultCurrentPage={3}></Pagination>
+    </div>
+)
+```
+
+### Capacity switching per page
+
+By setting `showSizeChanger` for `true`, allowing quick switching of capacity per page via the Select component
+
+```jsx live=true width=50%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination total={80} showSizeChanger></Pagination>
+        <br/>
+        <br/>
+        <Pagination total={300} showSizeChanger></Pagination>
+    </div>
+)
+```
+
+### Jump to a page quickly
+
+By setting `showQuickJumper` to `true`, you can enter the page number through the Input control to quickly jump  
+When Input loses focus, if there is a valid number in Input, it will jump directly. You can also enter the page number you want to jump to when the Input is focused, and then hit enter to jump directly  
+If you enter a page number greater than the total page number of the pager, we will automatically jump to the last page for you   
+showQuickJumper is available after v1.31  
+
+```jsx live=true width=50%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination total={80} showQuickJumper style={{ marginBottom: 12 }}></Pagination>
+        <Pagination total={300} showQuickJumper></Pagination>
+    </div>
+)
+```
+
+
+### Page number controlled
+
+After the currentPage is passed in, the pager is a controlled component and is generally used in conjunction with `onPageChange`. The current active page number depends entirely on the value of the `currentPage` passed in.
+
+```jsx live=true width=55%
+import React, { useState } from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => {
+    const [page, setPage] = useState(3);
+    function onPageChange(currentPage) {
+        setPage(currentPage);
+    }
+    return (
+        <Pagination
+            total={200}
+            currentPage={page}
+            onPageChange={onPageChange}>
+        </Pagination>
+    );
+}
+```
+
+### Preset capacity per page
+
+Specify an optional value for switching the capacity per page by using the `pageSizeOpts` array
+
+```jsx live=true width=50%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <div>
+        <Pagination
+            total={300}
+            showSizeChanger
+            pageSizeOpts={[50, 80, 90, 200]}>
+        </Pagination>
+        <br/>
+        <br/>
+        <Pagination
+            total={300}
+            showSizeChanger
+            pageSizeOpts={[10, 20, 50, 200]}>
+        </Pagination>
+    </div>
+)
+```
+
+### Mini version
+
+Show mini pagination via size properties.
+
+```jsx live=true width=55%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <Pagination total={90} size="small"></Pagination>
+)
+```
+
+Turn on hoverShowPageSelect to quickly switch hover page numbers (provided after v1.27.0)
+
+```jsx live=true width=50%
+import React from 'react';
+import { Pagination } from '@douyinfe/semi-ui';
+
+() => (
+    <Pagination total={90} size="small" hoverShowPageSelect></Pagination>
+)
+```
+
+## API reference
+
+| Properties         | Instructions                                                                                                | type                                            | Default             |   Version    |
+| ------------------ | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------- |------------- |
+| className          | The CSS class name of the wrapper element                                                                   | string                                          |                     |              |
+| currentPage        | Current page number                                                                                         | number                                          |                     |              |
+| defaultCurrentPage | Default current page number                                                                                 | number                                          |                     |              |
+| hideOnSinglePage   | Whether to hide the page divider automatically when the total number of pages is less than 2                | boolean                                         | false               |              |
+| hoverShowPageSelect  | Whether to show the page select when hover page (only work when size='small')                             | boolean                                         | false               |   1.27.0     |
+| nextText           | Text displayed by the next Page button                                                                      | string\| React Node                             |                     |              |
+| pageSize           | Number of entries per page                                                                                  | number                                          | 10                  |              |
+| pageSizeOpts       | Specify how many items are displayed per page                                                               | array                                           | \[10, 20, 40, 100\] |              |
+| popoverPosition    | Floating layer direction, visible [Popover·API reference·position](/en-US/show/popover#Use%20with%20Tooltip%20or%20Popconfirm) | string                                          | "bottomLeft"        |              |
+| popoverZIndix      | Floating layer z-index value                                                                                | number                                          |  1030               |              |
+| prevText           | Text displayed by the previous Page button                                                                  | string\| React Node                             |                     |              |
+| size               | Size, optional `small`, `default`                                                                           | string                                          | 'default'           |              |
+| style              | Inline style                                                                                                | object                                          |                     |              |
+| showSizeChanger    | Whether to show a selector to switch the capacity of each page                                              | boolean                                         | false               |              |
+| showQuickJumper    | Whether to show a input to type the page number, supported after v1.31                                      | boolean                                         | false               |   1.31.0     |
+| showTotal          | Whether to show total page number                                                                           | boolean                                         | 3                   |              |
+| total              | Total number of entries                                                                                     | number                                          | 1                   |              |
+| onChange           | The callback function when page number or capacity per page changes                                         | function(currentPage: number, pageSize: number) |                     |              |
+| onPageChange       | A callback function for page number changes                                                                 | function(currentPage: number)                   |                     |              |
+| onPageSize Change  | Callback function when capacity changes per page                                                            | function(pageSize: number)                      |                     |              |
+
+## Design Tokens
+<DesignToken/>
+
+## FAQ
+
+-   **Why is the page drop-down selector only `1,000,000` at most?**  
+    Because when creating lists, the browser has [restrictions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length) on the size of Array.from () to create arrays; At the same time, in order to take into account the overhead of Array.from(), we set the threshold of `1,000,000`.

部分文件因为文件数量过多而无法显示