#
tokens: 49281/50000 15/1152 files (page 17/52)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 17 of 52. Use http://codebase.md/alibaba/formily?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .all-contributorsrc
├── .codecov.yml
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .github
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE
│   │   └── config.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows
│       ├── check-pr-title.yml
│       ├── ci.yml
│       ├── commitlint.yml
│       ├── issue-open-check.yml
│       ├── package-size.yml
│       └── pr-welcome.yml
├── .gitignore
├── .prettierrc.js
├── .umirc.js
├── .vscode
│   └── cspell.json
├── .yarnrc
├── CHANGELOG.md
├── commitlint.config.js
├── devtools
│   ├── .eslintrc
│   └── chrome-extension
│       ├── .npmignore
│       ├── assets
│       │   └── img
│       │       ├── loading.svg
│       │       └── logo
│       │           ├── 128x128.png
│       │           ├── 16x16.png
│       │           ├── 38x38.png
│       │           ├── 48x48.png
│       │           ├── error.png
│       │           ├── gray.png
│       │           └── scalable.png
│       ├── config
│       │   ├── webpack.base.ts
│       │   ├── webpack.dev.ts
│       │   └── webpack.prod.ts
│       ├── LICENSE.md
│       ├── package.json
│       ├── src
│       │   ├── app
│       │   │   ├── components
│       │   │   │   ├── FieldTree.tsx
│       │   │   │   ├── filter.ts
│       │   │   │   ├── LeftPanel.tsx
│       │   │   │   ├── RightPanel.tsx
│       │   │   │   ├── SearchBox.tsx
│       │   │   │   └── Tabs.tsx
│       │   │   ├── demo.tsx
│       │   │   └── index.tsx
│       │   └── extension
│       │       ├── backend.ts
│       │       ├── background.ts
│       │       ├── content.ts
│       │       ├── devpanel.tsx
│       │       ├── devtools.tsx
│       │       ├── inject.ts
│       │       ├── manifest.json
│       │       ├── popup.tsx
│       │       └── views
│       │           ├── devpanel.ejs
│       │           ├── devtools.ejs
│       │           └── popup.ejs
│       ├── tsconfig.build.json
│       └── tsconfig.json
├── docs
│   ├── functions
│   │   ├── contributors.ts
│   │   └── npm-search.ts
│   ├── guide
│   │   ├── advanced
│   │   │   ├── async.md
│   │   │   ├── async.zh-CN.md
│   │   │   ├── build.md
│   │   │   ├── build.zh-CN.md
│   │   │   ├── business-logic.md
│   │   │   ├── business-logic.zh-CN.md
│   │   │   ├── calculator.md
│   │   │   ├── calculator.zh-CN.md
│   │   │   ├── controlled.md
│   │   │   ├── controlled.zh-CN.md
│   │   │   ├── custom.md
│   │   │   ├── custom.zh-CN.md
│   │   │   ├── destructor.md
│   │   │   ├── destructor.zh-CN.md
│   │   │   ├── input.less
│   │   │   ├── layout.md
│   │   │   ├── layout.zh-CN.md
│   │   │   ├── linkages.md
│   │   │   ├── linkages.zh-CN.md
│   │   │   ├── validate.md
│   │   │   └── validate.zh-CN.md
│   │   ├── contribution.md
│   │   ├── contribution.zh-CN.md
│   │   ├── form-builder.md
│   │   ├── form-builder.zh-CN.md
│   │   ├── index.md
│   │   ├── index.zh-CN.md
│   │   ├── issue-helper.md
│   │   ├── issue-helper.zh-CN.md
│   │   ├── learn-formily.md
│   │   ├── learn-formily.zh-CN.md
│   │   ├── quick-start.md
│   │   ├── quick-start.zh-CN.md
│   │   ├── scenes
│   │   │   ├── dialog-drawer.md
│   │   │   ├── dialog-drawer.zh-CN.md
│   │   │   ├── edit-detail.md
│   │   │   ├── edit-detail.zh-CN.md
│   │   │   ├── index.less
│   │   │   ├── login-register.md
│   │   │   ├── login-register.zh-CN.md
│   │   │   ├── more.md
│   │   │   ├── more.zh-CN.md
│   │   │   ├── query-list.md
│   │   │   ├── query-list.zh-CN.md
│   │   │   ├── step-form.md
│   │   │   ├── step-form.zh-CN.md
│   │   │   ├── tab-form.md
│   │   │   ├── tab-form.zh-CN.md
│   │   │   └── VerifyCode.tsx
│   │   ├── upgrade.md
│   │   └── upgrade.zh-CN.md
│   ├── index.md
│   ├── index.zh-CN.md
│   └── site
│       ├── Contributors.less
│       ├── Contributors.tsx
│       ├── QrCode.less
│       ├── QrCode.tsx
│       ├── Section.less
│       ├── Section.tsx
│       └── styles.less
├── global.config.ts
├── jest.config.js
├── lerna.json
├── LICENSE.md
├── package.json
├── packages
│   ├── .eslintrc
│   ├── antd
│   │   ├── __tests__
│   │   │   ├── moment.spec.ts
│   │   │   └── sideEffects.spec.ts
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── build-style.ts
│   │   ├── create-style.ts
│   │   ├── docs
│   │   │   ├── components
│   │   │   │   ├── ArrayCards.md
│   │   │   │   ├── ArrayCards.zh-CN.md
│   │   │   │   ├── ArrayCollapse.md
│   │   │   │   ├── ArrayCollapse.zh-CN.md
│   │   │   │   ├── ArrayItems.md
│   │   │   │   ├── ArrayItems.zh-CN.md
│   │   │   │   ├── ArrayTable.md
│   │   │   │   ├── ArrayTable.zh-CN.md
│   │   │   │   ├── ArrayTabs.md
│   │   │   │   ├── ArrayTabs.zh-CN.md
│   │   │   │   ├── Cascader.md
│   │   │   │   ├── Cascader.zh-CN.md
│   │   │   │   ├── Checkbox.md
│   │   │   │   ├── Checkbox.zh-CN.md
│   │   │   │   ├── DatePicker.md
│   │   │   │   ├── DatePicker.zh-CN.md
│   │   │   │   ├── Editable.md
│   │   │   │   ├── Editable.zh-CN.md
│   │   │   │   ├── Form.md
│   │   │   │   ├── Form.zh-CN.md
│   │   │   │   ├── FormButtonGroup.md
│   │   │   │   ├── FormButtonGroup.zh-CN.md
│   │   │   │   ├── FormCollapse.md
│   │   │   │   ├── FormCollapse.zh-CN.md
│   │   │   │   ├── FormDialog.md
│   │   │   │   ├── FormDialog.zh-CN.md
│   │   │   │   ├── FormDrawer.md
│   │   │   │   ├── FormDrawer.zh-CN.md
│   │   │   │   ├── FormGrid.md
│   │   │   │   ├── FormGrid.zh-CN.md
│   │   │   │   ├── FormItem.md
│   │   │   │   ├── FormItem.zh-CN.md
│   │   │   │   ├── FormLayout.md
│   │   │   │   ├── FormLayout.zh-CN.md
│   │   │   │   ├── FormStep.md
│   │   │   │   ├── FormStep.zh-CN.md
│   │   │   │   ├── FormTab.md
│   │   │   │   ├── FormTab.zh-CN.md
│   │   │   │   ├── index.md
│   │   │   │   ├── index.zh-CN.md
│   │   │   │   ├── Input.md
│   │   │   │   ├── Input.zh-CN.md
│   │   │   │   ├── NumberPicker.md
│   │   │   │   ├── NumberPicker.zh-CN.md
│   │   │   │   ├── Password.md
│   │   │   │   ├── Password.zh-CN.md
│   │   │   │   ├── PreviewText.md
│   │   │   │   ├── PreviewText.zh-CN.md
│   │   │   │   ├── Radio.md
│   │   │   │   ├── Radio.zh-CN.md
│   │   │   │   ├── Reset.md
│   │   │   │   ├── Reset.zh-CN.md
│   │   │   │   ├── Select.md
│   │   │   │   ├── Select.zh-CN.md
│   │   │   │   ├── SelectTable.md
│   │   │   │   ├── SelectTable.zh-CN.md
│   │   │   │   ├── Space.md
│   │   │   │   ├── Space.zh-CN.md
│   │   │   │   ├── Submit.md
│   │   │   │   ├── Submit.zh-CN.md
│   │   │   │   ├── Switch.md
│   │   │   │   ├── Switch.zh-CN.md
│   │   │   │   ├── TimePicker.md
│   │   │   │   ├── TimePicker.zh-CN.md
│   │   │   │   ├── Transfer.md
│   │   │   │   ├── Transfer.zh-CN.md
│   │   │   │   ├── TreeSelect.md
│   │   │   │   ├── TreeSelect.zh-CN.md
│   │   │   │   ├── Upload.md
│   │   │   │   └── Upload.zh-CN.md
│   │   │   ├── index.md
│   │   │   └── index.zh-CN.md
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __builtins__
│   │   │   │   ├── hooks
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── useClickAway.ts
│   │   │   │   │   └── usePrefixCls.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── loading.ts
│   │   │   │   ├── moment.ts
│   │   │   │   ├── pickDataProps.ts
│   │   │   │   ├── portal.tsx
│   │   │   │   ├── render.ts
│   │   │   │   └── sort.tsx
│   │   │   ├── array-base
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── array-cards
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── array-collapse
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── array-items
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── array-table
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── array-tabs
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── cascader
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── checkbox
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── date-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── editable
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── form
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── form-button-group
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── form-collapse
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-dialog
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-drawer
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-grid
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── form-item
│   │   │   │   ├── animation.less
│   │   │   │   ├── grid.less
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── form-layout
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   ├── style.ts
│   │   │   │   └── useResponsiveFormLayout.ts
│   │   │   ├── form-step
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-tab
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── index.ts
│   │   │   ├── input
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── number-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── password
│   │   │   │   ├── index.tsx
│   │   │   │   ├── PasswordStrength.tsx
│   │   │   │   └── style.ts
│   │   │   ├── preview-text
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── radio
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   └── style.ts
│   │   │   ├── reset
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── select
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── select-table
│   │   │   │   ├── index.tsx
│   │   │   │   ├── style.less
│   │   │   │   ├── style.ts
│   │   │   │   ├── useCheckSlackly.tsx
│   │   │   │   ├── useFilterOptions.tsx
│   │   │   │   ├── useFlatOptions.tsx
│   │   │   │   ├── useSize.tsx
│   │   │   │   ├── useTitleAddon.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── space
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── style.less
│   │   │   ├── style.ts
│   │   │   ├── submit
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── switch
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── time-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── transfer
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── tree-select
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   └── upload
│   │   │       ├── index.tsx
│   │   │       ├── placeholder.ts
│   │   │       └── style.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── benchmark
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   └── index.tsx
│   │   ├── template.ejs
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   ├── webpack.base.ts
│   │   ├── webpack.dev.ts
│   │   └── webpack.prod.ts
│   ├── core
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── docs
│   │   │   ├── api
│   │   │   │   ├── entry
│   │   │   │   │   ├── ActionResponse.less
│   │   │   │   │   ├── ActionResponse.tsx
│   │   │   │   │   ├── createForm.md
│   │   │   │   │   ├── createForm.zh-CN.md
│   │   │   │   │   ├── FieldEffectHooks.md
│   │   │   │   │   ├── FieldEffectHooks.zh-CN.md
│   │   │   │   │   ├── FormChecker.md
│   │   │   │   │   ├── FormChecker.zh-CN.md
│   │   │   │   │   ├── FormEffectHooks.md
│   │   │   │   │   ├── FormEffectHooks.zh-CN.md
│   │   │   │   │   ├── FormHooksAPI.md
│   │   │   │   │   ├── FormHooksAPI.zh-CN.md
│   │   │   │   │   ├── FormPath.md
│   │   │   │   │   ├── FormPath.zh-CN.md
│   │   │   │   │   ├── FormValidatorRegistry.md
│   │   │   │   │   └── FormValidatorRegistry.zh-CN.md
│   │   │   │   └── models
│   │   │   │       ├── ArrayField.md
│   │   │   │       ├── ArrayField.zh-CN.md
│   │   │   │       ├── Field.md
│   │   │   │       ├── Field.zh-CN.md
│   │   │   │       ├── Form.md
│   │   │   │       ├── Form.zh-CN.md
│   │   │   │       ├── ObjectField.md
│   │   │   │       ├── ObjectField.zh-CN.md
│   │   │   │       ├── Query.md
│   │   │   │       ├── Query.zh-CN.md
│   │   │   │       ├── VoidField.md
│   │   │   │       └── VoidField.zh-CN.md
│   │   │   ├── guide
│   │   │   │   ├── architecture.md
│   │   │   │   ├── architecture.zh-CN.md
│   │   │   │   ├── field.md
│   │   │   │   ├── field.zh-CN.md
│   │   │   │   ├── form.md
│   │   │   │   ├── form.zh-CN.md
│   │   │   │   ├── index.md
│   │   │   │   ├── index.zh-CN.md
│   │   │   │   ├── mvvm.md
│   │   │   │   ├── mvvm.zh-CN.md
│   │   │   │   ├── values.md
│   │   │   │   └── values.zh-CN.md
│   │   │   ├── index.md
│   │   │   └── index.zh-CN.md
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── array.spec.ts
│   │   │   │   ├── effects.spec.ts
│   │   │   │   ├── externals.spec.ts
│   │   │   │   ├── field.spec.ts
│   │   │   │   ├── form.spec.ts
│   │   │   │   ├── graph.spec.ts
│   │   │   │   ├── heart.spec.ts
│   │   │   │   ├── internals.spec.ts
│   │   │   │   ├── lifecycle.spec.ts
│   │   │   │   ├── object.spec.ts
│   │   │   │   ├── shared.ts
│   │   │   │   └── void.spec.ts
│   │   │   ├── effects
│   │   │   │   ├── index.ts
│   │   │   │   ├── onFieldEffects.ts
│   │   │   │   └── onFormEffects.ts
│   │   │   ├── global.d.ts
│   │   │   ├── index.ts
│   │   │   ├── models
│   │   │   │   ├── ArrayField.ts
│   │   │   │   ├── BaseField.ts
│   │   │   │   ├── Field.ts
│   │   │   │   ├── Form.ts
│   │   │   │   ├── Graph.ts
│   │   │   │   ├── Heart.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── LifeCycle.ts
│   │   │   │   ├── ObjectField.ts
│   │   │   │   ├── Query.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── VoidField.ts
│   │   │   ├── shared
│   │   │   │   ├── checkers.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── effective.ts
│   │   │   │   ├── externals.ts
│   │   │   │   └── internals.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── element
│   │   ├── .npmignore
│   │   ├── build-style.ts
│   │   ├── create-style.ts
│   │   ├── docs
│   │   │   ├── .vuepress
│   │   │   │   ├── components
│   │   │   │   │   ├── createCodeSandBox.js
│   │   │   │   │   ├── dumi-previewer.vue
│   │   │   │   │   └── highlight.js
│   │   │   │   ├── config.js
│   │   │   │   ├── enhanceApp.js
│   │   │   │   ├── styles
│   │   │   │   │   └── index.styl
│   │   │   │   └── util.js
│   │   │   ├── demos
│   │   │   │   ├── guide
│   │   │   │   │   ├── array-cards
│   │   │   │   │   │   ├── effects-json-schema.vue
│   │   │   │   │   │   ├── effects-markup-schema.vue
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── array-collapse
│   │   │   │   │   │   ├── effects-json-schema.vue
│   │   │   │   │   │   ├── effects-markup-schema.vue
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── array-items
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── array-table
│   │   │   │   │   │   ├── effects-json-schema.vue
│   │   │   │   │   │   ├── effects-markup-schema.vue
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── array-tabs
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── cascader
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── checkbox
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── date-picker
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── editable
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── form-button-group.vue
│   │   │   │   │   ├── form-collapse
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── form-dialog
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── form-drawer
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── form-grid
│   │   │   │   │   │   ├── form.vue
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── native.vue
│   │   │   │   │   ├── form-item
│   │   │   │   │   │   ├── bordered-none.vue
│   │   │   │   │   │   ├── common.vue
│   │   │   │   │   │   ├── feedback.vue
│   │   │   │   │   │   ├── inset.vue
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   ├── size.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── form-layout
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── form-step
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── form-tab
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   └── markup-schema.vue
│   │   │   │   │   ├── form.vue
│   │   │   │   │   ├── input
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── input-number
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── password
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── preview-text
│   │   │   │   │   │   ├── base.vue
│   │   │   │   │   │   └── extend.vue
│   │   │   │   │   ├── radio
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── reset
│   │   │   │   │   │   ├── base.vue
│   │   │   │   │   │   ├── force.vue
│   │   │   │   │   │   └── validate.vue
│   │   │   │   │   ├── select
│   │   │   │   │   │   ├── json-schema-async.vue
│   │   │   │   │   │   ├── json-schema-sync.vue
│   │   │   │   │   │   ├── markup-schema-async-search.vue
│   │   │   │   │   │   ├── markup-schema-async.vue
│   │   │   │   │   │   ├── markup-schema-sync.vue
│   │   │   │   │   │   ├── template-async.vue
│   │   │   │   │   │   └── template-sync.vue
│   │   │   │   │   ├── space
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── submit
│   │   │   │   │   │   ├── base.vue
│   │   │   │   │   │   └── loading.vue
│   │   │   │   │   ├── switch
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── time-picker
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   ├── transfer
│   │   │   │   │   │   ├── json-schema.vue
│   │   │   │   │   │   ├── markup-schema.vue
│   │   │   │   │   │   └── template.vue
│   │   │   │   │   └── upload
│   │   │   │   │       ├── json-schema.vue
│   │   │   │   │       ├── markup-schema.vue
│   │   │   │   │       └── template.vue
│   │   │   │   └── index.vue
│   │   │   ├── guide
│   │   │   │   ├── array-cards.md
│   │   │   │   ├── array-collapse.md
│   │   │   │   ├── array-items.md
│   │   │   │   ├── array-table.md
│   │   │   │   ├── array-tabs.md
│   │   │   │   ├── cascader.md
│   │   │   │   ├── checkbox.md
│   │   │   │   ├── date-picker.md
│   │   │   │   ├── editable.md
│   │   │   │   ├── form-button-group.md
│   │   │   │   ├── form-collapse.md
│   │   │   │   ├── form-dialog.md
│   │   │   │   ├── form-drawer.md
│   │   │   │   ├── form-grid.md
│   │   │   │   ├── form-item.md
│   │   │   │   ├── form-layout.md
│   │   │   │   ├── form-step.md
│   │   │   │   ├── form-tab.md
│   │   │   │   ├── form.md
│   │   │   │   ├── index.md
│   │   │   │   ├── input-number.md
│   │   │   │   ├── input.md
│   │   │   │   ├── password.md
│   │   │   │   ├── preview-text.md
│   │   │   │   ├── radio.md
│   │   │   │   ├── reset.md
│   │   │   │   ├── select.md
│   │   │   │   ├── space.md
│   │   │   │   ├── submit.md
│   │   │   │   ├── switch.md
│   │   │   │   ├── time-picker.md
│   │   │   │   ├── transfer.md
│   │   │   │   └── upload.md
│   │   │   └── README.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __builtins__
│   │   │   │   ├── configs
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── shared
│   │   │   │   │   ├── create-context.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── loading.ts
│   │   │   │   │   ├── portal.ts
│   │   │   │   │   ├── resolve-component.ts
│   │   │   │   │   ├── transform-component.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   └── styles
│   │   │   │       └── common.scss
│   │   │   ├── array-base
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-cards
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-collapse
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-items
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-table
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-tabs
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── cascader
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── checkbox
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── date-picker
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── editable
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── el-form
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── el-form-item
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── form
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-button-group
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-collapse
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-dialog
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── form-drawer
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-grid
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-item
│   │   │   │   ├── animation.scss
│   │   │   │   ├── grid.scss
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   ├── style.ts
│   │   │   │   └── var.scss
│   │   │   ├── form-layout
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   ├── style.ts
│   │   │   │   └── useResponsiveFormLayout.ts
│   │   │   ├── form-step
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── form-tab
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── index.ts
│   │   │   ├── input
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── input-number
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── password
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── preview-text
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── radio
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── reset
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── select
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── space
│   │   │   │   ├── index.ts
│   │   │   │   ├── style.scss
│   │   │   │   └── style.ts
│   │   │   ├── style.ts
│   │   │   ├── submit
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── switch
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── time-picker
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   ├── transfer
│   │   │   │   ├── index.ts
│   │   │   │   └── style.ts
│   │   │   └── upload
│   │   │       ├── index.ts
│   │   │       └── style.ts
│   │   ├── transformer.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── grid
│   │   ├── .npmignore
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── index.ts
│   │   │   └── observer.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── json-schema
│   │   ├── .npmignore
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── __snapshots__
│   │   │   │   │   └── schema.spec.ts.snap
│   │   │   │   ├── compiler.spec.ts
│   │   │   │   ├── patches.spec.ts
│   │   │   │   ├── schema.spec.ts
│   │   │   │   ├── server-validate.spec.ts
│   │   │   │   ├── shared.spec.ts
│   │   │   │   ├── transformer.spec.ts
│   │   │   │   └── traverse.spec.ts
│   │   │   ├── compiler.ts
│   │   │   ├── global.d.ts
│   │   │   ├── index.ts
│   │   │   ├── patches.ts
│   │   │   ├── polyfills
│   │   │   │   ├── index.ts
│   │   │   │   └── SPECIFICATION_1_0.ts
│   │   │   ├── schema.ts
│   │   │   ├── shared.ts
│   │   │   ├── transformer.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── next
│   │   ├── __tests__
│   │   │   ├── moment.spec.ts
│   │   │   └── sideEffects.spec.ts
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── build-style.ts
│   │   ├── create-style.ts
│   │   ├── docs
│   │   │   ├── components
│   │   │   │   ├── ArrayCards.md
│   │   │   │   ├── ArrayCards.zh-CN.md
│   │   │   │   ├── ArrayCollapse.md
│   │   │   │   ├── ArrayCollapse.zh-CN.md
│   │   │   │   ├── ArrayItems.md
│   │   │   │   ├── ArrayItems.zh-CN.md
│   │   │   │   ├── ArrayTable.md
│   │   │   │   ├── ArrayTable.zh-CN.md
│   │   │   │   ├── Cascader.md
│   │   │   │   ├── Cascader.zh-CN.md
│   │   │   │   ├── Checkbox.md
│   │   │   │   ├── Checkbox.zh-CN.md
│   │   │   │   ├── DatePicker.md
│   │   │   │   ├── DatePicker.zh-CN.md
│   │   │   │   ├── DatePicker2.md
│   │   │   │   ├── DatePicker2.zh-CN.md
│   │   │   │   ├── Editable.md
│   │   │   │   ├── Editable.zh-CN.md
│   │   │   │   ├── Form.md
│   │   │   │   ├── Form.zh-CN.md
│   │   │   │   ├── FormButtonGroup.md
│   │   │   │   ├── FormButtonGroup.zh-CN.md
│   │   │   │   ├── FormCollapse.md
│   │   │   │   ├── FormCollapse.zh-CN.md
│   │   │   │   ├── FormDialog.md
│   │   │   │   ├── FormDialog.zh-CN.md
│   │   │   │   ├── FormDrawer.md
│   │   │   │   ├── FormDrawer.zh-CN.md
│   │   │   │   ├── FormGrid.md
│   │   │   │   ├── FormGrid.zh-CN.md
│   │   │   │   ├── FormItem.md
│   │   │   │   ├── FormItem.zh-CN.md
│   │   │   │   ├── FormLayout.md
│   │   │   │   ├── FormLayout.zh-CN.md
│   │   │   │   ├── FormStep.md
│   │   │   │   ├── FormStep.zh-CN.md
│   │   │   │   ├── FormTab.md
│   │   │   │   ├── FormTab.zh-CN.md
│   │   │   │   ├── index.md
│   │   │   │   ├── index.zh-CN.md
│   │   │   │   ├── Input.md
│   │   │   │   ├── Input.zh-CN.md
│   │   │   │   ├── NumberPicker.md
│   │   │   │   ├── NumberPicker.zh-CN.md
│   │   │   │   ├── Password.md
│   │   │   │   ├── Password.zh-CN.md
│   │   │   │   ├── PreviewText.md
│   │   │   │   ├── PreviewText.zh-CN.md
│   │   │   │   ├── Radio.md
│   │   │   │   ├── Radio.zh-CN.md
│   │   │   │   ├── Reset.md
│   │   │   │   ├── Reset.zh-CN.md
│   │   │   │   ├── Select.md
│   │   │   │   ├── Select.zh-CN.md
│   │   │   │   ├── SelectTable.md
│   │   │   │   ├── SelectTable.zh-CN.md
│   │   │   │   ├── Space.md
│   │   │   │   ├── Space.zh-CN.md
│   │   │   │   ├── Submit.md
│   │   │   │   ├── Submit.zh-CN.md
│   │   │   │   ├── Switch.md
│   │   │   │   ├── Switch.zh-CN.md
│   │   │   │   ├── TimePicker.md
│   │   │   │   ├── TimePicker.zh-CN.md
│   │   │   │   ├── TimePicker2.md
│   │   │   │   ├── TimePicker2.zh-CN.md
│   │   │   │   ├── Transfer.md
│   │   │   │   ├── Transfer.zh-CN.md
│   │   │   │   ├── TreeSelect.md
│   │   │   │   ├── TreeSelect.zh-CN.md
│   │   │   │   ├── Upload.md
│   │   │   │   └── Upload.zh-CN.md
│   │   │   ├── index.md
│   │   │   └── index.zh-CN.md
│   │   ├── LESENCE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __builtins__
│   │   │   │   ├── empty.tsx
│   │   │   │   ├── hooks
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── useClickAway.ts
│   │   │   │   │   └── usePrefixCls.ts
│   │   │   │   ├── icons.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── loading.ts
│   │   │   │   ├── mapSize.ts
│   │   │   │   ├── mapStatus.ts
│   │   │   │   ├── moment.ts
│   │   │   │   ├── pickDataProps.ts
│   │   │   │   ├── portal.tsx
│   │   │   │   ├── render.ts
│   │   │   │   └── toArray.ts
│   │   │   ├── array-base
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-cards
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-collapse
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-items
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── array-table
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── cascader
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── checkbox
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── date-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── date-picker2
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── editable
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── form
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-button-group
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-collapse
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-dialog
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-drawer
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-grid
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-item
│   │   │   │   ├── animation.scss
│   │   │   │   ├── grid.scss
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   ├── scss
│   │   │   │   │   └── variable.scss
│   │   │   │   └── style.ts
│   │   │   ├── form-layout
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   ├── style.ts
│   │   │   │   └── useResponsiveFormLayout.ts
│   │   │   ├── form-step
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── form-tab
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── index.ts
│   │   │   ├── input
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── main.scss
│   │   │   ├── number-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── password
│   │   │   │   ├── index.tsx
│   │   │   │   ├── PasswordStrength.tsx
│   │   │   │   └── style.ts
│   │   │   ├── preview-text
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── radio
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── reset
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── select
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── select-table
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   ├── style.ts
│   │   │   │   ├── useCheckSlackly.tsx
│   │   │   │   ├── useFilterOptions.tsx
│   │   │   │   ├── useFlatOptions.tsx
│   │   │   │   ├── useSize.tsx
│   │   │   │   ├── useTitleAddon.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── space
│   │   │   │   ├── index.tsx
│   │   │   │   ├── main.scss
│   │   │   │   └── style.ts
│   │   │   ├── style.ts
│   │   │   ├── submit
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── switch
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── time-picker
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── time-picker2
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── transfer
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   ├── tree-select
│   │   │   │   ├── index.tsx
│   │   │   │   └── style.ts
│   │   │   └── upload
│   │   │       ├── index.tsx
│   │   │       ├── main.scss
│   │   │       ├── placeholder.ts
│   │   │       └── style.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── path
│   │   ├── .npmignore
│   │   ├── benchmark.ts
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── accessor.spec.ts
│   │   │   │   ├── basic.spec.ts
│   │   │   │   ├── match.spec.ts
│   │   │   │   ├── parser.spec.ts
│   │   │   │   └── share.spec.ts
│   │   │   ├── contexts.ts
│   │   │   ├── destructor.ts
│   │   │   ├── index.ts
│   │   │   ├── matcher.ts
│   │   │   ├── parser.ts
│   │   │   ├── shared.ts
│   │   │   ├── tokenizer.ts
│   │   │   ├── tokens.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── react
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── docs
│   │   │   ├── api
│   │   │   │   ├── components
│   │   │   │   │   ├── ArrayField.md
│   │   │   │   │   ├── ArrayField.zh-CN.md
│   │   │   │   │   ├── ExpressionScope.md
│   │   │   │   │   ├── ExpressionScope.zh-CN.md
│   │   │   │   │   ├── Field.md
│   │   │   │   │   ├── Field.zh-CN.md
│   │   │   │   │   ├── FormConsumer.md
│   │   │   │   │   ├── FormConsumer.zh-CN.md
│   │   │   │   │   ├── FormProvider.md
│   │   │   │   │   ├── FormProvider.zh-CN.md
│   │   │   │   │   ├── ObjectField.md
│   │   │   │   │   ├── ObjectField.zh-CN.md
│   │   │   │   │   ├── RecordScope.md
│   │   │   │   │   ├── RecordScope.zh-CN.md
│   │   │   │   │   ├── RecordsScope.md
│   │   │   │   │   ├── RecordsScope.zh-CN.md
│   │   │   │   │   ├── RecursionField.md
│   │   │   │   │   ├── RecursionField.zh-CN.md
│   │   │   │   │   ├── SchemaField.md
│   │   │   │   │   ├── SchemaField.zh-CN.md
│   │   │   │   │   ├── VoidField.md
│   │   │   │   │   └── VoidField.zh-CN.md
│   │   │   │   ├── hooks
│   │   │   │   │   ├── useExpressionScope.md
│   │   │   │   │   ├── useExpressionScope.zh-CN.md
│   │   │   │   │   ├── useField.md
│   │   │   │   │   ├── useField.zh-CN.md
│   │   │   │   │   ├── useFieldSchema.md
│   │   │   │   │   ├── useFieldSchema.zh-CN.md
│   │   │   │   │   ├── useForm.md
│   │   │   │   │   ├── useForm.zh-CN.md
│   │   │   │   │   ├── useFormEffects.md
│   │   │   │   │   ├── useFormEffects.zh-CN.md
│   │   │   │   │   ├── useParentForm.md
│   │   │   │   │   └── useParentForm.zh-CN.md
│   │   │   │   └── shared
│   │   │   │       ├── connect.md
│   │   │   │       ├── connect.zh-CN.md
│   │   │   │       ├── context.md
│   │   │   │       ├── context.zh-CN.md
│   │   │   │       ├── mapProps.md
│   │   │   │       ├── mapProps.zh-CN.md
│   │   │   │       ├── mapReadPretty.md
│   │   │   │       ├── mapReadPretty.zh-CN.md
│   │   │   │       ├── observer.md
│   │   │   │       ├── observer.zh-CN.md
│   │   │   │       ├── Schema.md
│   │   │   │       └── Schema.zh-CN.md
│   │   │   ├── guide
│   │   │   │   ├── architecture.md
│   │   │   │   ├── architecture.zh-CN.md
│   │   │   │   ├── concept.md
│   │   │   │   ├── concept.zh-CN.md
│   │   │   │   ├── index.md
│   │   │   │   └── index.zh-CN.md
│   │   │   ├── index.md
│   │   │   └── index.zh-CN.md
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── expression.spec.tsx
│   │   │   │   ├── field.spec.tsx
│   │   │   │   ├── form.spec.tsx
│   │   │   │   ├── schema.json.spec.tsx
│   │   │   │   ├── schema.markup.spec.tsx
│   │   │   │   └── shared.tsx
│   │   │   ├── components
│   │   │   │   ├── ArrayField.tsx
│   │   │   │   ├── ExpressionScope.tsx
│   │   │   │   ├── Field.tsx
│   │   │   │   ├── FormConsumer.tsx
│   │   │   │   ├── FormProvider.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── ObjectField.tsx
│   │   │   │   ├── ReactiveField.tsx
│   │   │   │   ├── RecordScope.tsx
│   │   │   │   ├── RecordsScope.tsx
│   │   │   │   ├── RecursionField.tsx
│   │   │   │   ├── SchemaField.tsx
│   │   │   │   └── VoidField.tsx
│   │   │   ├── global.d.ts
│   │   │   ├── hooks
│   │   │   │   ├── index.ts
│   │   │   │   ├── useAttach.ts
│   │   │   │   ├── useExpressionScope.ts
│   │   │   │   ├── useField.ts
│   │   │   │   ├── useFieldSchema.ts
│   │   │   │   ├── useForm.ts
│   │   │   │   ├── useFormEffects.ts
│   │   │   │   └── useParentForm.ts
│   │   │   ├── index.ts
│   │   │   ├── shared
│   │   │   │   ├── connect.ts
│   │   │   │   ├── context.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── render.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── reactive
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── benchmark.ts
│   │   ├── docs
│   │   │   ├── api
│   │   │   │   ├── action.md
│   │   │   │   ├── action.zh-CN.md
│   │   │   │   ├── autorun.md
│   │   │   │   ├── autorun.zh-CN.md
│   │   │   │   ├── batch.md
│   │   │   │   ├── batch.zh-CN.md
│   │   │   │   ├── define.md
│   │   │   │   ├── define.zh-CN.md
│   │   │   │   ├── hasCollected.md
│   │   │   │   ├── hasCollected.zh-CN.md
│   │   │   │   ├── markObservable.md
│   │   │   │   ├── markObservable.zh-CN.md
│   │   │   │   ├── markRaw.md
│   │   │   │   ├── markRaw.zh-CN.md
│   │   │   │   ├── model.md
│   │   │   │   ├── model.zh-CN.md
│   │   │   │   ├── observable.md
│   │   │   │   ├── observable.zh-CN.md
│   │   │   │   ├── observe.md
│   │   │   │   ├── observe.zh-CN.md
│   │   │   │   ├── raw.md
│   │   │   │   ├── raw.zh-CN.md
│   │   │   │   ├── react
│   │   │   │   │   ├── observer.md
│   │   │   │   │   └── observer.zh-CN.md
│   │   │   │   ├── reaction.md
│   │   │   │   ├── reaction.zh-CN.md
│   │   │   │   ├── toJS.md
│   │   │   │   ├── toJS.zh-CN.md
│   │   │   │   ├── tracker.md
│   │   │   │   ├── tracker.zh-CN.md
│   │   │   │   ├── typeChecker.md
│   │   │   │   ├── typeChecker.zh-CN.md
│   │   │   │   ├── untracked.md
│   │   │   │   ├── untracked.zh-CN.md
│   │   │   │   └── vue
│   │   │   │       ├── observer.md
│   │   │   │       └── observer.zh-CN.md
│   │   │   ├── guide
│   │   │   │   ├── best-practice.md
│   │   │   │   ├── best-practice.zh-CN.md
│   │   │   │   ├── concept.md
│   │   │   │   ├── concept.zh-CN.md
│   │   │   │   ├── index.md
│   │   │   │   └── index.zh-CN.md
│   │   │   ├── index.md
│   │   │   └── index.zh-CN.md
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── action.spec.ts
│   │   │   │   ├── annotations.spec.ts
│   │   │   │   ├── array.spec.ts
│   │   │   │   ├── autorun.spec.ts
│   │   │   │   ├── batch.spec.ts
│   │   │   │   ├── collections-map.spec.ts
│   │   │   │   ├── collections-set.spec.ts
│   │   │   │   ├── collections-weakmap.spec.ts
│   │   │   │   ├── collections-weakset.spec.ts
│   │   │   │   ├── define.spec.ts
│   │   │   │   ├── externals.spec.ts
│   │   │   │   ├── hasCollected.spec.ts
│   │   │   │   ├── observable.spec.ts
│   │   │   │   ├── observe.spec.ts
│   │   │   │   ├── tracker.spec.ts
│   │   │   │   └── untracked.spec.ts
│   │   │   ├── action.ts
│   │   │   ├── annotations
│   │   │   │   ├── box.ts
│   │   │   │   ├── computed.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── observable.ts
│   │   │   │   ├── ref.ts
│   │   │   │   └── shallow.ts
│   │   │   ├── array.ts
│   │   │   ├── autorun.ts
│   │   │   ├── batch.ts
│   │   │   ├── checkers.ts
│   │   │   ├── environment.ts
│   │   │   ├── externals.ts
│   │   │   ├── global.d.ts
│   │   │   ├── handlers.ts
│   │   │   ├── index.ts
│   │   │   ├── internals.ts
│   │   │   ├── model.ts
│   │   │   ├── observable.ts
│   │   │   ├── observe.ts
│   │   │   ├── reaction.ts
│   │   │   ├── tracker.ts
│   │   │   ├── tree.ts
│   │   │   ├── types.ts
│   │   │   └── untracked.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── reactive-react
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── hooks
│   │   │   │   ├── index.ts
│   │   │   │   ├── useCompatEffect.ts
│   │   │   │   ├── useCompatFactory.ts
│   │   │   │   ├── useDidUpdate.ts
│   │   │   │   ├── useForceUpdate.ts
│   │   │   │   ├── useLayoutEffect.ts
│   │   │   │   └── useObserver.ts
│   │   │   ├── index.ts
│   │   │   ├── observer.ts
│   │   │   ├── shared
│   │   │   │   ├── gc.ts
│   │   │   │   ├── global.ts
│   │   │   │   ├── immediate.ts
│   │   │   │   └── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── reactive-test-cases-for-react18
│   │   ├── .npmignore
│   │   ├── .umirc.js
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── index.js
│   │   │   └── MySlowList.js
│   │   ├── template.ejs
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   ├── webpack.base.ts
│   │   ├── webpack.dev.ts
│   │   └── webpack.prod.ts
│   ├── reactive-vue
│   │   ├── .npmignore
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   └── observer.spec.ts
│   │   │   ├── hooks
│   │   │   │   ├── index.ts
│   │   │   │   └── useObserver.ts
│   │   │   ├── index.ts
│   │   │   ├── observer
│   │   │   │   ├── collectData.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── observerInVue2.ts
│   │   │   │   └── observerInVue3.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── shared
│   │   ├── .npmignore
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   └── index.spec.ts
│   │   │   ├── array.ts
│   │   │   ├── case.ts
│   │   │   ├── checkers.ts
│   │   │   ├── clone.ts
│   │   │   ├── compare.ts
│   │   │   ├── defaults.ts
│   │   │   ├── deprecate.ts
│   │   │   ├── global.ts
│   │   │   ├── index.ts
│   │   │   ├── instanceof.ts
│   │   │   ├── isEmpty.ts
│   │   │   ├── merge.ts
│   │   │   ├── middleware.ts
│   │   │   ├── path.ts
│   │   │   ├── string.ts
│   │   │   ├── subscribable.ts
│   │   │   └── uid.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   ├── validator
│   │   ├── .npmignore
│   │   ├── LICENSE.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── rollup.config.js
│   │   ├── src
│   │   │   ├── __tests__
│   │   │   │   ├── parser.spec.ts
│   │   │   │   ├── registry.spec.ts
│   │   │   │   └── validator.spec.ts
│   │   │   ├── formats.ts
│   │   │   ├── index.ts
│   │   │   ├── locale.ts
│   │   │   ├── parser.ts
│   │   │   ├── registry.ts
│   │   │   ├── rules.ts
│   │   │   ├── template.ts
│   │   │   ├── types.ts
│   │   │   └── validator.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   └── vue
│       ├── .npmignore
│       ├── bin
│       │   ├── formily-vue-fix.js
│       │   └── formily-vue-switch.js
│       ├── docs
│       │   ├── .vuepress
│       │   │   ├── components
│       │   │   │   ├── createCodeSandBox.js
│       │   │   │   ├── dumi-previewer.vue
│       │   │   │   └── highlight.js
│       │   │   ├── config.js
│       │   │   ├── enhanceApp.js
│       │   │   └── styles
│       │   │       └── index.styl
│       │   ├── api
│       │   │   ├── components
│       │   │   │   ├── array-field.md
│       │   │   │   ├── expression-scope.md
│       │   │   │   ├── field.md
│       │   │   │   ├── form-consumer.md
│       │   │   │   ├── form-provider.md
│       │   │   │   ├── object-field.md
│       │   │   │   ├── recursion-field-with-component.md
│       │   │   │   ├── recursion-field.md
│       │   │   │   ├── schema-field-with-schema.md
│       │   │   │   ├── schema-field.md
│       │   │   │   └── void-field.md
│       │   │   ├── hooks
│       │   │   │   ├── use-field-schema.md
│       │   │   │   ├── use-field.md
│       │   │   │   ├── use-form-effects.md
│       │   │   │   ├── use-form.md
│       │   │   │   └── use-parent-form.md
│       │   │   └── shared
│       │   │       ├── connect.md
│       │   │       ├── injections.md
│       │   │       ├── map-props.md
│       │   │       ├── map-read-pretty.md
│       │   │       ├── observer.md
│       │   │       └── schema.md
│       │   ├── demos
│       │   │   ├── api
│       │   │   │   ├── components
│       │   │   │   │   ├── array-field.vue
│       │   │   │   │   ├── expression-scope.vue
│       │   │   │   │   ├── field.vue
│       │   │   │   │   ├── form-consumer.vue
│       │   │   │   │   ├── form-provider.vue
│       │   │   │   │   ├── object-field.vue
│       │   │   │   │   ├── recursion-field-with-component.vue
│       │   │   │   │   ├── recursion-field.vue
│       │   │   │   │   ├── schema-field-with-schema.vue
│       │   │   │   │   ├── schema-field.vue
│       │   │   │   │   └── void-field.vue
│       │   │   │   ├── hooks
│       │   │   │   │   ├── use-field-schema.vue
│       │   │   │   │   ├── use-field.vue
│       │   │   │   │   ├── use-form-effects.vue
│       │   │   │   │   ├── use-form.vue
│       │   │   │   │   └── use-parent-form.vue
│       │   │   │   └── shared
│       │   │   │       ├── connect.vue
│       │   │   │       ├── map-props.vue
│       │   │   │       ├── map-read-pretty.vue
│       │   │   │       └── observer.vue
│       │   │   ├── index.vue
│       │   │   └── questions
│       │   │       ├── default-slot.vue
│       │   │       ├── events.vue
│       │   │       ├── named-slot.vue
│       │   │       └── scoped-slot.vue
│       │   ├── guide
│       │   │   ├── architecture.md
│       │   │   ├── concept.md
│       │   │   └── README.md
│       │   ├── questions
│       │   │   └── README.md
│       │   └── README.md
│       ├── package.json
│       ├── README.md
│       ├── rollup.config.js
│       ├── scripts
│       │   ├── postinstall.js
│       │   ├── switch-cli.js
│       │   └── utils.js
│       ├── src
│       │   ├── __tests__
│       │   │   ├── expression.scope.spec.ts
│       │   │   ├── field.spec.ts
│       │   │   ├── form.spec.ts
│       │   │   ├── schema.json.spec.ts
│       │   │   ├── schema.markup.spec.ts
│       │   │   ├── shared.spec.ts
│       │   │   └── utils.spec.ts
│       │   ├── components
│       │   │   ├── ArrayField.ts
│       │   │   ├── ExpressionScope.ts
│       │   │   ├── Field.ts
│       │   │   ├── FormConsumer.ts
│       │   │   ├── FormProvider.ts
│       │   │   ├── index.ts
│       │   │   ├── ObjectField.ts
│       │   │   ├── ReactiveField.ts
│       │   │   ├── RecursionField.ts
│       │   │   ├── SchemaField.ts
│       │   │   └── VoidField.ts
│       │   ├── global.d.ts
│       │   ├── hooks
│       │   │   ├── index.ts
│       │   │   ├── useAttach.ts
│       │   │   ├── useField.ts
│       │   │   ├── useFieldSchema.ts
│       │   │   ├── useForm.ts
│       │   │   ├── useFormEffects.ts
│       │   │   ├── useInjectionCleaner.ts
│       │   │   └── useParentForm.ts
│       │   ├── index.ts
│       │   ├── shared
│       │   │   ├── connect.ts
│       │   │   ├── context.ts
│       │   │   ├── createForm.ts
│       │   │   ├── fragment.ts
│       │   │   ├── h.ts
│       │   │   └── index.ts
│       │   ├── types
│       │   │   └── index.ts
│       │   ├── utils
│       │   │   ├── formatVNodeData.ts
│       │   │   ├── getFieldProps.ts
│       │   │   ├── getRawComponent.ts
│       │   │   └── resolveSchemaProps.ts
│       │   └── vue2-components.ts
│       ├── tsconfig.build.json
│       ├── tsconfig.json
│       └── tsconfig.types.json
├── README.md
├── README.zh-cn.md
├── scripts
│   ├── build-style
│   │   ├── buildAllStyles.ts
│   │   ├── copy.ts
│   │   ├── helper.ts
│   │   └── index.ts
│   └── rollup.base.js
├── tsconfig.build.json
├── tsconfig.jest.json
├── tsconfig.json
└── yarn.lock
```

# Files

--------------------------------------------------------------------------------
/packages/antd/src/upload/index.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import React, { useEffect } from 'react'
  2 | import { Field } from '@formily/core'
  3 | import { connect, mapProps, useField } from '@formily/react'
  4 | import { Upload as AntdUpload, Button } from 'antd'
  5 | import {
  6 |   UploadChangeParam,
  7 |   UploadProps as AntdUploadProps,
  8 |   DraggerProps as AntdDraggerProps,
  9 | } from 'antd/lib/upload'
 10 | import { InboxOutlined, UploadOutlined } from '@ant-design/icons'
 11 | import { reaction } from '@formily/reactive'
 12 | import { UploadFile } from 'antd/lib/upload/interface'
 13 | import { isArr, toArr } from '@formily/shared'
 14 | import { UPLOAD_PLACEHOLDER } from './placeholder'
 15 | import { usePrefixCls } from '../__builtins__'
 16 | 
 17 | export type IUploadProps = Omit<AntdUploadProps, 'onChange'> & {
 18 |   textContent?: React.ReactNode
 19 |   onChange?: (fileList: UploadFile[]) => void
 20 |   serviceErrorMessage?: string
 21 | }
 22 | 
 23 | export type IDraggerUploadProps = Omit<AntdDraggerProps, 'onChange'> & {
 24 |   textContent?: React.ReactNode
 25 |   onChange?: (fileList: UploadFile[]) => void
 26 |   serviceErrorMessage?: string
 27 | }
 28 | 
 29 | type ComposedUpload = React.FC<React.PropsWithChildren<IUploadProps>> & {
 30 |   Dragger?: React.FC<React.PropsWithChildren<IDraggerUploadProps>>
 31 | }
 32 | 
 33 | type IExtendsUploadProps = {
 34 |   fileList?: any[]
 35 |   serviceErrorMessage?: string
 36 |   onChange?: (...args: any) => void
 37 | }
 38 | 
 39 | const testOpts = (
 40 |   ext: RegExp,
 41 |   options: { exclude?: string[]; include?: string[] }
 42 | ) => {
 43 |   if (options && isArr(options.include)) {
 44 |     return options.include.some((url) => ext.test(url))
 45 |   }
 46 | 
 47 |   if (options && isArr(options.exclude)) {
 48 |     return !options.exclude.some((url) => ext.test(url))
 49 |   }
 50 | 
 51 |   return true
 52 | }
 53 | 
 54 | const getImageByUrl = (url: string, options: any) => {
 55 |   for (let i = 0; i < UPLOAD_PLACEHOLDER.length; i++) {
 56 |     if (
 57 |       UPLOAD_PLACEHOLDER[i].ext.test(url) &&
 58 |       testOpts(UPLOAD_PLACEHOLDER[i].ext, options)
 59 |     ) {
 60 |       return UPLOAD_PLACEHOLDER[i].icon || url
 61 |     }
 62 |   }
 63 | 
 64 |   return url
 65 | }
 66 | 
 67 | const getURL = (target: any) => {
 68 |   return target?.['url'] || target?.['downloadURL'] || target?.['imgURL']
 69 | }
 70 | const getThumbURL = (target: any) => {
 71 |   return (
 72 |     target?.['thumbUrl'] ||
 73 |     target?.['url'] ||
 74 |     target?.['downloadURL'] ||
 75 |     target?.['imgURL']
 76 |   )
 77 | }
 78 | 
 79 | const getErrorMessage = (target: any) => {
 80 |   return (
 81 |     target?.errorMessage ||
 82 |     target?.errMsg ||
 83 |     target?.errorMsg ||
 84 |     target?.message ||
 85 |     (typeof target?.error === 'string' ? target.error : '')
 86 |   )
 87 | }
 88 | 
 89 | const getState = (target: any) => {
 90 |   if (target?.success === false) return 'error'
 91 |   if (target?.failed === true) return 'error'
 92 |   if (target?.error) return 'error'
 93 |   return target?.state || target?.status
 94 | }
 95 | 
 96 | const normalizeFileList = (fileList: UploadFile[]) => {
 97 |   if (fileList && fileList.length) {
 98 |     return fileList.map((file, index) => {
 99 |       return {
100 |         ...file,
101 |         uid: file.uid || `${index}`,
102 |         status: getState(file.response) || getState(file),
103 |         url: getURL(file) || getURL(file?.response),
104 |         thumbUrl: getImageByUrl(
105 |           getThumbURL(file) || getThumbURL(file?.response),
106 |           {
107 |             exclude: ['.png', '.jpg', '.jpeg', '.gif'],
108 |           }
109 |         ),
110 |       }
111 |     })
112 |   }
113 |   return []
114 | }
115 | 
116 | const useValidator = (validator: (value: any) => string) => {
117 |   const field = useField<Field>()
118 |   useEffect(() => {
119 |     const dispose = reaction(
120 |       () => field.value,
121 |       (value) => {
122 |         const message = validator(value)
123 |         field.setFeedback({
124 |           type: 'error',
125 |           code: 'UploadError',
126 |           messages: message ? [message] : [],
127 |         })
128 |       }
129 |     )
130 |     return () => {
131 |       dispose()
132 |     }
133 |   }, [])
134 | }
135 | 
136 | const useUploadValidator = (serviceErrorMessage = 'Upload Service Error') => {
137 |   useValidator((value) => {
138 |     const list = toArr(value)
139 |     for (let i = 0; i < list.length; i++) {
140 |       if (list[i]?.status === 'error') {
141 |         return (
142 |           getErrorMessage(list[i]?.response) ||
143 |           getErrorMessage(list[i]) ||
144 |           serviceErrorMessage
145 |         )
146 |       }
147 |     }
148 |   })
149 | }
150 | 
151 | function useUploadProps<T extends IExtendsUploadProps = IUploadProps>({
152 |   serviceErrorMessage,
153 |   ...props
154 | }: T) {
155 |   useUploadValidator(serviceErrorMessage)
156 |   const onChange = (param: UploadChangeParam<UploadFile>) => {
157 |     props.onChange?.(normalizeFileList([...param.fileList]))
158 |   }
159 |   return {
160 |     ...props,
161 |     fileList: normalizeFileList(props.fileList),
162 |     onChange,
163 |   }
164 | }
165 | 
166 | const getPlaceholder = (props: IUploadProps) => {
167 |   if (props.listType !== 'picture-card') {
168 |     return (
169 |       <Button>
170 |         <UploadOutlined />
171 |         {props.textContent}
172 |       </Button>
173 |     )
174 |   }
175 |   return <UploadOutlined style={{ fontSize: 20 }} />
176 | }
177 | 
178 | export const Upload: ComposedUpload = connect(
179 |   (props: React.PropsWithChildren<IUploadProps>) => {
180 |     return (
181 |       <AntdUpload {...useUploadProps(props)}>
182 |         {props.children || getPlaceholder(props)}
183 |       </AntdUpload>
184 |     )
185 |   },
186 |   mapProps({
187 |     value: 'fileList',
188 |   })
189 | )
190 | 
191 | const Dragger = connect(
192 |   (props: React.PropsWithChildren<IDraggerUploadProps>) => {
193 |     return (
194 |       <div className={usePrefixCls('upload-dragger')}>
195 |         <AntdUpload.Dragger {...useUploadProps(props)}>
196 |           {props.children || (
197 |             <React.Fragment>
198 |               <p className="ant-upload-drag-icon">
199 |                 <InboxOutlined />
200 |               </p>
201 |               {props.textContent && (
202 |                 <p className="ant-upload-text">{props.textContent}</p>
203 |               )}
204 |             </React.Fragment>
205 |           )}
206 |         </AntdUpload.Dragger>
207 |       </div>
208 |     )
209 |   },
210 |   mapProps({
211 |     value: 'fileList',
212 |   })
213 | )
214 | 
215 | Upload.Dragger = Dragger
216 | 
217 | export default Upload
218 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/DatePicker2.md:
--------------------------------------------------------------------------------

```markdown
  1 | # DatePicker2
  2 | 
  3 | > Date Picker
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'
 10 | import { createForm } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | 
 13 | const SchemaField = createSchemaField({
 14 |   components: {
 15 |     DatePicker2,
 16 |     FormItem,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => (
 23 |   <FormProvider form={form}>
 24 |     <SchemaField>
 25 |       <SchemaField.String
 26 |         name="date"
 27 |         title="normal date"
 28 |         x-decorator="FormItem"
 29 |         x-component="DatePicker2"
 30 |       />
 31 |       <SchemaField.String
 32 |         name="week"
 33 |         title="Week Selection"
 34 |         x-decorator="FormItem"
 35 |         x-component="DatePicker2.WeekPicker"
 36 |       />
 37 |       <SchemaField.String
 38 |         name="month"
 39 |         title="Month Selection"
 40 |         x-decorator="FormItem"
 41 |         x-component="DatePicker2.MonthPicker"
 42 |       />
 43 |       <SchemaField.String
 44 |         name="year"
 45 |         title="Year selection"
 46 |         x-decorator="FormItem"
 47 |         x-component="DatePicker2.YearPicker"
 48 |       />
 49 |       <SchemaField.String
 50 |         name="[startDate,endDate]"
 51 |         title="Date Range"
 52 |         x-decorator="FormItem"
 53 |         x-component="DatePicker2.RangePicker"
 54 |         x-component-props={{
 55 |           showTime: true,
 56 |         }}
 57 |       />
 58 |       <SchemaField.String
 59 |         name="range_month"
 60 |         title="Month Range Selection"
 61 |         x-decorator="FormItem"
 62 |         x-component="DatePicker2.RangePicker"
 63 |         x-component-props={{
 64 |           mode: 'month',
 65 |         }}
 66 |       />
 67 |       <SchemaField.String
 68 |         name="range_year"
 69 |         title="Year range selection"
 70 |         x-decorator="FormItem"
 71 |         x-component="DatePicker2.RangePicker"
 72 |         x-component-props={{
 73 |           mode: 'year',
 74 |         }}
 75 |       />
 76 |     </SchemaField>
 77 |     <FormButtonGroup>
 78 |       <Submit onSubmit={console.log}>Submit</Submit>
 79 |     </FormButtonGroup>
 80 |   </FormProvider>
 81 | )
 82 | ```
 83 | 
 84 | ## JSON Schema case
 85 | 
 86 | ```tsx
 87 | import React from 'react'
 88 | import { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'
 89 | import { createForm } from '@formily/core'
 90 | import { FormProvider, createSchemaField } from '@formily/react'
 91 | 
 92 | const SchemaField = createSchemaField({
 93 |   components: {
 94 |     DatePicker2,
 95 |     FormItem,
 96 |   },
 97 | })
 98 | 
 99 | const form = createForm()
100 | 
101 | const schema = {
102 |   type: 'object',
103 |   properties: {
104 |     date: {
105 |       title: 'Normal date',
106 |       'x-decorator': 'FormItem',
107 |       'x-component': 'DatePicker2',
108 |       type: 'string',
109 |     },
110 |     week: {
111 |       title: 'Week Selection',
112 |       'x-decorator': 'FormItem',
113 |       'x-component': 'DatePicker2.WeekPicker',
114 |       type: 'string',
115 |     },
116 |     month: {
117 |       title: 'Month Selection',
118 |       'x-decorator': 'FormItem',
119 |       'x-component': 'DatePicker2.MonthPicker',
120 |       type: 'string',
121 |     },
122 |     year: {
123 |       title: 'Year selection',
124 |       'x-decorator': 'FormItem',
125 |       'x-component': 'DatePicker2.YearPicker',
126 |       type: 'string',
127 |     },
128 |     '[startDate,endDate]': {
129 |       title: 'Date range',
130 |       'x-decorator': 'FormItem',
131 |       'x-component': 'DatePicker2.RangePicker',
132 |       'x-component-props': {
133 |         showTime: true,
134 |       },
135 |       type: 'string',
136 |     },
137 |     range_month: {
138 |       title: 'Month Range Selection',
139 |       'x-decorator': 'FormItem',
140 |       'x-component': 'DatePicker2.RangePicker',
141 |       'x-component-props': {
142 |         mode: 'month',
143 |       },
144 |       type: 'string',
145 |     },
146 |     range_year: {
147 |       name: 'range_year',
148 |       title: 'Year range selection',
149 |       'x-decorator': 'FormItem',
150 |       'x-component': 'DatePicker2.RangePicker',
151 |       'x-component-props': {
152 |         mode: 'year',
153 |       },
154 |       type: 'string',
155 |     },
156 |   },
157 | }
158 | 
159 | export default () => (
160 |   <FormProvider form={form}>
161 |     <SchemaField schema={schema} />
162 |     <FormButtonGroup>
163 |       <Submit onSubmit={console.log}>Submit</Submit>
164 |     </FormButtonGroup>
165 |   </FormProvider>
166 | )
167 | ```
168 | 
169 | ## Pure JSX case
170 | 
171 | ```tsx
172 | import React from 'react'
173 | import { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'
174 | import { createForm } from '@formily/core'
175 | import { FormProvider, Field } from '@formily/react'
176 | 
177 | const form = createForm()
178 | 
179 | export default () => (
180 |   <FormProvider form={form}>
181 |     <Field
182 |       name="date"
183 |       title="date selection"
184 |       decorator={[FormItem]}
185 |       component={[DatePicker2]}
186 |     />
187 |     <Field
188 |       name="week"
189 |       title="Week Selection"
190 |       decorator={[FormItem]}
191 |       component={[DatePicker2.WeekPicker]}
192 |     />
193 |     <Field
194 |       name="quarter"
195 |       title="Financial Year Selection"
196 |       decorator={[FormItem]}
197 |       component={[DatePicker2.MonthPicker]}
198 |     />
199 |     <Field
200 |       name="year"
201 |       title="Year selection"
202 |       decorator={[FormItem]}
203 |       component={[DatePicker2.YearPicker]}
204 |     />
205 |     <Field
206 |       name="[startDate,endDate]"
207 |       title="Date range selection"
208 |       decorator={[FormItem]}
209 |       component={[DatePicker2.RangePicker]}
210 |     />
211 |     <Field
212 |       name="range_month"
213 |       title="Month Range Selection"
214 |       decorator={[FormItem]}
215 |       component={[
216 |         DatePicker2.RangePicker,
217 |         {
218 |           mode: 'month',
219 |         },
220 |       ]}
221 |     />
222 |     <Field
223 |       name="range_year"
224 |       title="Year range selection"
225 |       decorator={[FormItem]}
226 |       component={[
227 |         DatePicker2.RangePicker,
228 |         {
229 |           mode: 'year',
230 |         },
231 |       ]}
232 |     />
233 |     <FormButtonGroup>
234 |       <Submit onSubmit={console.log}>Submit</Submit>
235 |     </FormButtonGroup>
236 |   </FormProvider>
237 | )
238 | ```
239 | 
240 | ## API
241 | 
242 | Reference https://fusion.design/pc/component/basic/date-picker2
243 | 
```

--------------------------------------------------------------------------------
/packages/antd/docs/components/FormTab.zh-CN.md:
--------------------------------------------------------------------------------

```markdown
  1 | # FormTab
  2 | 
  3 | > 选项卡表单
  4 | >
  5 | > 注意:该组件只适用于 Schema 场景
  6 | 
  7 | ## Markup Schema 案例
  8 | 
  9 | ```tsx
 10 | import React from 'react'
 11 | import {
 12 |   FormTab,
 13 |   FormItem,
 14 |   Input,
 15 |   FormButtonGroup,
 16 |   Submit,
 17 | } from '@formily/antd'
 18 | import { createForm } from '@formily/core'
 19 | import { FormProvider, createSchemaField } from '@formily/react'
 20 | import { Button } from 'antd'
 21 | 
 22 | const SchemaField = createSchemaField({
 23 |   components: {
 24 |     FormItem,
 25 |     FormTab,
 26 |     Input,
 27 |   },
 28 | })
 29 | 
 30 | const form = createForm()
 31 | const formTab = FormTab.createFormTab()
 32 | 
 33 | export default () => {
 34 |   return (
 35 |     <FormProvider form={form}>
 36 |       <SchemaField>
 37 |         <SchemaField.Void
 38 |           type="void"
 39 |           x-component="FormTab"
 40 |           x-component-props={{ formTab }}
 41 |         >
 42 |           <SchemaField.Void
 43 |             type="void"
 44 |             name="tab1"
 45 |             x-component="FormTab.TabPane"
 46 |             x-component-props={{ tab: 'A1' }}
 47 |           >
 48 |             <SchemaField.String
 49 |               name="aaa"
 50 |               x-decorator="FormItem"
 51 |               title="AAA"
 52 |               required
 53 |               x-component="Input"
 54 |             />
 55 |           </SchemaField.Void>
 56 |           <SchemaField.Void
 57 |             name="tab2"
 58 |             x-component="FormTab.TabPane"
 59 |             x-component-props={{ tab: 'A2' }}
 60 |           >
 61 |             <SchemaField.String
 62 |               name="bbb"
 63 |               x-decorator="FormItem"
 64 |               title="BBB"
 65 |               required
 66 |               x-component="Input"
 67 |             />
 68 |           </SchemaField.Void>
 69 |           <SchemaField.Void
 70 |             name="tab3"
 71 |             x-component="FormTab.TabPane"
 72 |             x-component-props={{ tab: 'A3' }}
 73 |           >
 74 |             <SchemaField.String
 75 |               name="ccc"
 76 |               x-decorator="FormItem"
 77 |               title="CCC"
 78 |               required
 79 |               x-component="Input"
 80 |             />
 81 |           </SchemaField.Void>
 82 |         </SchemaField.Void>
 83 |       </SchemaField>
 84 |       <FormButtonGroup.FormItem>
 85 |         <Button
 86 |           onClick={() => {
 87 |             form.query('tab3').take((field) => {
 88 |               field.visible = !field.visible
 89 |             })
 90 |           }}
 91 |         >
 92 |           显示/隐藏最后一个Tab
 93 |         </Button>
 94 |         <Button
 95 |           onClick={() => {
 96 |             formTab.setActiveKey('tab2')
 97 |           }}
 98 |         >
 99 |           切换第二个Tab
100 |         </Button>
101 |         <Submit onSubmit={console.log}>提交</Submit>
102 |       </FormButtonGroup.FormItem>
103 |     </FormProvider>
104 |   )
105 | }
106 | ```
107 | 
108 | ## JSON Schema 案例
109 | 
110 | ```tsx
111 | import React from 'react'
112 | import {
113 |   FormTab,
114 |   FormItem,
115 |   Input,
116 |   FormButtonGroup,
117 |   Submit,
118 | } from '@formily/antd'
119 | import { createForm } from '@formily/core'
120 | import { FormProvider, createSchemaField } from '@formily/react'
121 | import { Button } from 'antd'
122 | 
123 | const SchemaField = createSchemaField({
124 |   components: {
125 |     FormItem,
126 |     FormTab,
127 |     Input,
128 |   },
129 | })
130 | 
131 | const form = createForm()
132 | const formTab = FormTab.createFormTab()
133 | 
134 | const schema = {
135 |   type: 'object',
136 |   properties: {
137 |     collapse: {
138 |       type: 'void',
139 |       'x-component': 'FormTab',
140 |       'x-component-props': {
141 |         formTab: '{{formTab}}',
142 |       },
143 |       properties: {
144 |         tab1: {
145 |           type: 'void',
146 |           'x-component': 'FormTab.TabPane',
147 |           'x-component-props': {
148 |             tab: 'A1',
149 |           },
150 |           properties: {
151 |             aaa: {
152 |               type: 'string',
153 |               title: 'AAA',
154 |               'x-decorator': 'FormItem',
155 |               required: true,
156 |               'x-component': 'Input',
157 |             },
158 |           },
159 |         },
160 |         tab2: {
161 |           type: 'void',
162 |           'x-component': 'FormTab.TabPane',
163 |           'x-component-props': {
164 |             tab: 'A2',
165 |           },
166 |           properties: {
167 |             bbb: {
168 |               type: 'string',
169 |               title: 'BBB',
170 |               'x-decorator': 'FormItem',
171 |               required: true,
172 |               'x-component': 'Input',
173 |             },
174 |           },
175 |         },
176 |         tab3: {
177 |           type: 'void',
178 |           'x-component': 'FormTab.TabPane',
179 |           'x-component-props': {
180 |             tab: 'A3',
181 |           },
182 |           properties: {
183 |             ccc: {
184 |               type: 'string',
185 |               title: 'CCC',
186 |               'x-decorator': 'FormItem',
187 |               required: true,
188 |               'x-component': 'Input',
189 |             },
190 |           },
191 |         },
192 |       },
193 |     },
194 |   },
195 | }
196 | 
197 | export default () => {
198 |   return (
199 |     <FormProvider form={form}>
200 |       <SchemaField schema={schema} scope={{ formTab }} />
201 |       <FormButtonGroup.FormItem>
202 |         <Button
203 |           onClick={() => {
204 |             form.query('tab3').take((field) => {
205 |               field.visible = !field.visible
206 |             })
207 |           }}
208 |         >
209 |           显示/隐藏最后一个Tab
210 |         </Button>
211 |         <Button
212 |           onClick={() => {
213 |             formTab.setActiveKey('tab2')
214 |           }}
215 |         >
216 |           切换第二个Tab
217 |         </Button>
218 |         <Submit onSubmit={console.log}>提交</Submit>
219 |       </FormButtonGroup.FormItem>
220 |     </FormProvider>
221 |   )
222 | }
223 | ```
224 | 
225 | ## API
226 | 
227 | ### FormTab
228 | 
229 | | 属性名  | 类型     | 描述                                             | 默认值 |
230 | | ------- | -------- | ------------------------------------------------ | ------ |
231 | | formTab | IFormTab | 传入通过 createFormTab/useFormTab 创建出来的模型 |        |
232 | 
233 | 其余参考 https://ant.design/components/tabs-cn/
234 | 
235 | ### FormTab.TabPane
236 | 
237 | 参考 https://ant.design/components/tabs-cn/
238 | 
239 | ### FormTab.createFormTab
240 | 
241 | ```ts pure
242 | type ActiveKey = string | number
243 | 
244 | interface createFormTab {
245 |   (defaultActiveKey?: ActiveKey): IFormTab
246 | }
247 | 
248 | interface IFormTab {
249 |   //激活主键
250 |   activeKey: ActiveKey
251 |   //设置激活主键
252 |   setActiveKey(key: ActiveKey): void
253 | }
254 | ```
255 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/FormTab.zh-CN.md:
--------------------------------------------------------------------------------

```markdown
  1 | # FormTab
  2 | 
  3 | > 选项卡表单
  4 | >
  5 | > 注意:该组件只适用于 Schema 场景
  6 | 
  7 | ## Markup Schema 案例
  8 | 
  9 | ```tsx
 10 | import React from 'react'
 11 | import {
 12 |   FormTab,
 13 |   FormItem,
 14 |   Input,
 15 |   FormButtonGroup,
 16 |   Submit,
 17 | } from '@formily/next'
 18 | import { createForm } from '@formily/core'
 19 | import { FormProvider, createSchemaField } from '@formily/react'
 20 | import { Button } from '@alifd/next'
 21 | 
 22 | const SchemaField = createSchemaField({
 23 |   components: {
 24 |     FormItem,
 25 |     FormTab,
 26 |     Input,
 27 |   },
 28 | })
 29 | 
 30 | const form = createForm()
 31 | const formTab = FormTab.createFormTab()
 32 | 
 33 | export default () => {
 34 |   return (
 35 |     <FormProvider form={form}>
 36 |       <SchemaField>
 37 |         <SchemaField.Void
 38 |           type="void"
 39 |           x-component="FormTab"
 40 |           x-component-props={{ formTab }}
 41 |         >
 42 |           <SchemaField.Void
 43 |             type="void"
 44 |             name="tab1"
 45 |             x-component="FormTab.TabPane"
 46 |             x-component-props={{ tab: 'A1' }}
 47 |           >
 48 |             <SchemaField.String
 49 |               name="aaa"
 50 |               x-decorator="FormItem"
 51 |               title="AAA"
 52 |               required
 53 |               x-component="Input"
 54 |             />
 55 |           </SchemaField.Void>
 56 |           <SchemaField.Void
 57 |             name="tab2"
 58 |             x-component="FormTab.TabPane"
 59 |             x-component-props={{ tab: 'A2' }}
 60 |           >
 61 |             <SchemaField.String
 62 |               name="bbb"
 63 |               x-decorator="FormItem"
 64 |               title="BBB"
 65 |               required
 66 |               x-component="Input"
 67 |             />
 68 |           </SchemaField.Void>
 69 |           <SchemaField.Void
 70 |             name="tab3"
 71 |             x-component="FormTab.TabPane"
 72 |             x-component-props={{ tab: 'A3' }}
 73 |           >
 74 |             <SchemaField.String
 75 |               name="ccc"
 76 |               x-decorator="FormItem"
 77 |               title="CCC"
 78 |               required
 79 |               x-component="Input"
 80 |             />
 81 |           </SchemaField.Void>
 82 |         </SchemaField.Void>
 83 |       </SchemaField>
 84 |       <FormButtonGroup.FormItem>
 85 |         <Button
 86 |           onClick={() => {
 87 |             form.query('tab3').take((field) => {
 88 |               field.visible = !field.visible
 89 |             })
 90 |           }}
 91 |         >
 92 |           显示/隐藏最后一个Tab
 93 |         </Button>
 94 |         <Button
 95 |           onClick={() => {
 96 |             formTab.setActiveKey('tab2')
 97 |           }}
 98 |         >
 99 |           切换第二个Tab
100 |         </Button>
101 |         <Submit onSubmit={console.log}>提交</Submit>
102 |       </FormButtonGroup.FormItem>
103 |     </FormProvider>
104 |   )
105 | }
106 | ```
107 | 
108 | ## JSON Schema 案例
109 | 
110 | ```tsx
111 | import React from 'react'
112 | import {
113 |   FormTab,
114 |   FormItem,
115 |   Input,
116 |   FormButtonGroup,
117 |   Submit,
118 | } from '@formily/next'
119 | import { createForm } from '@formily/core'
120 | import { FormProvider, createSchemaField } from '@formily/react'
121 | import { Button } from '@alifd/next'
122 | 
123 | const SchemaField = createSchemaField({
124 |   components: {
125 |     FormItem,
126 |     FormTab,
127 |     Input,
128 |   },
129 | })
130 | 
131 | const form = createForm()
132 | const formTab = FormTab.createFormTab()
133 | 
134 | const schema = {
135 |   type: 'object',
136 |   properties: {
137 |     collapse: {
138 |       type: 'void',
139 |       'x-component': 'FormTab',
140 |       'x-component-props': {
141 |         formTab: '{{formTab}}',
142 |       },
143 |       properties: {
144 |         tab1: {
145 |           type: 'void',
146 |           'x-component': 'FormTab.TabPane',
147 |           'x-component-props': {
148 |             tab: 'A1',
149 |           },
150 |           properties: {
151 |             aaa: {
152 |               type: 'string',
153 |               title: 'AAA',
154 |               'x-decorator': 'FormItem',
155 |               required: true,
156 |               'x-component': 'Input',
157 |             },
158 |           },
159 |         },
160 |         tab2: {
161 |           type: 'void',
162 |           'x-component': 'FormTab.TabPane',
163 |           'x-component-props': {
164 |             tab: 'A2',
165 |           },
166 |           properties: {
167 |             bbb: {
168 |               type: 'string',
169 |               title: 'BBB',
170 |               'x-decorator': 'FormItem',
171 |               required: true,
172 |               'x-component': 'Input',
173 |             },
174 |           },
175 |         },
176 |         tab3: {
177 |           type: 'void',
178 |           'x-component': 'FormTab.TabPane',
179 |           'x-component-props': {
180 |             tab: 'A3',
181 |           },
182 |           properties: {
183 |             ccc: {
184 |               type: 'string',
185 |               title: 'CCC',
186 |               'x-decorator': 'FormItem',
187 |               required: true,
188 |               'x-component': 'Input',
189 |             },
190 |           },
191 |         },
192 |       },
193 |     },
194 |   },
195 | }
196 | 
197 | export default () => {
198 |   return (
199 |     <FormProvider form={form}>
200 |       <SchemaField schema={schema} scope={{ formTab }} />
201 |       <FormButtonGroup.FormItem>
202 |         <Button
203 |           onClick={() => {
204 |             form.query('tab3').take((field) => {
205 |               field.visible = !field.visible
206 |             })
207 |           }}
208 |         >
209 |           显示/隐藏最后一个Tab
210 |         </Button>
211 |         <Button
212 |           onClick={() => {
213 |             formTab.setActiveKey('tab2')
214 |           }}
215 |         >
216 |           切换第二个Tab
217 |         </Button>
218 |         <Submit onSubmit={console.log}>提交</Submit>
219 |       </FormButtonGroup.FormItem>
220 |     </FormProvider>
221 |   )
222 | }
223 | ```
224 | 
225 | ## API
226 | 
227 | ### FormTab
228 | 
229 | | 属性名  | 类型     | 描述                                             | 默认值 |
230 | | ------- | -------- | ------------------------------------------------ | ------ |
231 | | formTab | IFormTab | 传入通过 createFormTab/useFormTab 创建出来的模型 |        |
232 | 
233 | 其余参考 https://fusion.design/pc/component/basic/tab
234 | 
235 | ### FormTab.TabPane
236 | 
237 | 参考 https://fusion.design/pc/component/basic/tab 的 Item 属性
238 | 
239 | ### FormTab.createFormTab
240 | 
241 | ```ts pure
242 | type ActiveKey = string | number
243 | 
244 | interface createFormTab {
245 |   (defaultActiveKey?: ActiveKey): IFormTab
246 | }
247 | 
248 | interface IFormTab {
249 |   //激活主键
250 |   activeKey: ActiveKey
251 |   //设置激活主键
252 |   setActiveKey(key: ActiveKey): void
253 | }
254 | ```
255 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/Cascader.zh-CN.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Cascader
  2 | 
  3 | > 联级选择器
  4 | 
  5 | ## Markup Schema 案例
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
 10 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | import { action } from '@formily/reactive'
 13 | 
 14 | const SchemaField = createSchemaField({
 15 |   components: {
 16 |     Cascader,
 17 |     FormItem,
 18 |   },
 19 | })
 20 | 
 21 | const useAddress = (pattern: FormPathPattern) => {
 22 |   const transform = (data = {}) => {
 23 |     return Object.entries(data).reduce((buf, [key, value]) => {
 24 |       if (typeof value === 'string')
 25 |         return buf.concat({
 26 |           label: value,
 27 |           value: key,
 28 |         })
 29 |       const { name, code, cities, districts } = value
 30 |       const _cities = transform(cities)
 31 |       const _districts = transform(districts)
 32 |       return buf.concat({
 33 |         label: name,
 34 |         value: code,
 35 |         children: _cities.length
 36 |           ? _cities
 37 |           : _districts.length
 38 |           ? _districts
 39 |           : undefined,
 40 |       })
 41 |     }, [])
 42 |   }
 43 |   onFieldReact(pattern, (field) => {
 44 |     field.loading = true
 45 |     fetch('//unpkg.com/china-location/dist/location.json')
 46 |       .then((res) => res.json())
 47 |       .then(
 48 |         action.bound((data) => {
 49 |           field.dataSource = transform(data)
 50 |           field.loading = false
 51 |         })
 52 |       )
 53 |   })
 54 | }
 55 | 
 56 | const form = createForm({
 57 |   effects: () => {
 58 |     useAddress('address')
 59 |   },
 60 | })
 61 | 
 62 | export default () => (
 63 |   <FormProvider form={form}>
 64 |     <SchemaField>
 65 |       <SchemaField.String
 66 |         name="address"
 67 |         title="地址选择"
 68 |         x-decorator="FormItem"
 69 |         x-component="Cascader"
 70 |         x-component-props={{
 71 |           style: {
 72 |             width: 240,
 73 |           },
 74 |         }}
 75 |       />
 76 |     </SchemaField>
 77 |     <FormButtonGroup>
 78 |       <Submit onSubmit={console.log}>提交</Submit>
 79 |     </FormButtonGroup>
 80 |   </FormProvider>
 81 | )
 82 | ```
 83 | 
 84 | ## JSON Schema 案例
 85 | 
 86 | ```tsx
 87 | import React from 'react'
 88 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
 89 | import { createForm } from '@formily/core'
 90 | import { FormProvider, createSchemaField } from '@formily/react'
 91 | import { action } from '@formily/reactive'
 92 | 
 93 | const SchemaField = createSchemaField({
 94 |   components: {
 95 |     Cascader,
 96 |     FormItem,
 97 |   },
 98 | })
 99 | 
100 | const transformAddress = (data = {}) => {
101 |   return Object.entries(data).reduce((buf, [key, value]) => {
102 |     if (typeof value === 'string')
103 |       return buf.concat({
104 |         label: value,
105 |         value: key,
106 |       })
107 |     const { name, code, cities, districts } = value
108 |     const _cities = transformAddress(cities)
109 |     const _districts = transformAddress(districts)
110 |     return buf.concat({
111 |       label: name,
112 |       value: code,
113 |       children: _cities.length
114 |         ? _cities
115 |         : _districts.length
116 |         ? _districts
117 |         : undefined,
118 |     })
119 |   }, [])
120 | }
121 | 
122 | const useAsyncDataSource =
123 |   (url: string, transform: (data: any) => any) => (field) => {
124 |     field.loading = true
125 |     fetch(url)
126 |       .then((res) => res.json())
127 |       .then(
128 |         action.bound((data) => {
129 |           field.dataSource = transform(data)
130 |           field.loading = false
131 |         })
132 |       )
133 |   }
134 | 
135 | const form = createForm()
136 | 
137 | const schema = {
138 |   type: 'object',
139 |   properties: {
140 |     address: {
141 |       type: 'string',
142 |       title: '地址选择',
143 |       'x-decorator': 'FormItem',
144 |       'x-component': 'Cascader',
145 |       'x-component-props': {
146 |         style: {
147 |           width: 240,
148 |         },
149 |       },
150 |       'x-reactions': [
151 |         '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}',
152 |       ],
153 |     },
154 |   },
155 | }
156 | 
157 | export default () => (
158 |   <FormProvider form={form}>
159 |     <SchemaField
160 |       schema={schema}
161 |       scope={{ useAsyncDataSource, transformAddress }}
162 |     />
163 |     <FormButtonGroup>
164 |       <Submit onSubmit={console.log}>提交</Submit>
165 |     </FormButtonGroup>
166 |   </FormProvider>
167 | )
168 | ```
169 | 
170 | ## 纯 JSX 案例
171 | 
172 | ```tsx
173 | import React from 'react'
174 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
175 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
176 | import { FormProvider, Field } from '@formily/react'
177 | import { action } from '@formily/reactive'
178 | 
179 | const useAddress = (pattern: FormPathPattern) => {
180 |   const transform = (data = {}) => {
181 |     return Object.entries(data).reduce((buf, [key, value]) => {
182 |       if (typeof value === 'string')
183 |         return buf.concat({
184 |           label: value,
185 |           value: key,
186 |         })
187 |       const { name, code, cities, districts } = value
188 |       const _cities = transform(cities)
189 |       const _districts = transform(districts)
190 |       return buf.concat({
191 |         label: name,
192 |         value: code,
193 |         children: _cities.length
194 |           ? _cities
195 |           : _districts.length
196 |           ? _districts
197 |           : undefined,
198 |       })
199 |     }, [])
200 |   }
201 |   onFieldReact(pattern, (field) => {
202 |     field.loading = true
203 |     fetch('//unpkg.com/china-location/dist/location.json')
204 |       .then((res) => res.json())
205 |       .then(
206 |         action.bound((data) => {
207 |           field.dataSource = transform(data)
208 |           field.loading = false
209 |         })
210 |       )
211 |   })
212 | }
213 | 
214 | const form = createForm({
215 |   effects: () => {
216 |     useAddress('address')
217 |   },
218 | })
219 | 
220 | export default () => (
221 |   <FormProvider form={form}>
222 |     <Field
223 |       name="address"
224 |       title="地址选择"
225 |       decorator={[FormItem]}
226 |       component={[
227 |         Cascader,
228 |         {
229 |           style: {
230 |             width: 240,
231 |           },
232 |         },
233 |       ]}
234 |     />
235 |     <FormButtonGroup>
236 |       <Submit onSubmit={console.log}>提交</Submit>
237 |     </FormButtonGroup>
238 |   </FormProvider>
239 | )
240 | ```
241 | 
242 | ## API
243 | 
244 | 参考 https://fusion.design/pc/component/basic/cascader-select
245 | 
```

--------------------------------------------------------------------------------
/packages/antd/docs/components/Cascader.zh-CN.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Cascader
  2 | 
  3 | > 联级选择器
  4 | 
  5 | ## Markup Schema 案例
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 10 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | import { action } from '@formily/reactive'
 13 | 
 14 | const SchemaField = createSchemaField({
 15 |   components: {
 16 |     Cascader,
 17 |     FormItem,
 18 |   },
 19 | })
 20 | 
 21 | const useAddress = (pattern: FormPathPattern) => {
 22 |   const transform = (data = {}) => {
 23 |     return Object.entries(data).reduce((buf, [key, value]) => {
 24 |       if (typeof value === 'string')
 25 |         return buf.concat({
 26 |           label: value,
 27 |           value: key,
 28 |         })
 29 |       const { name, code, cities, districts } = value
 30 |       const _cities = transform(cities)
 31 |       const _districts = transform(districts)
 32 |       return buf.concat({
 33 |         label: name,
 34 |         value: code,
 35 |         children: _cities.length
 36 |           ? _cities
 37 |           : _districts.length
 38 |           ? _districts
 39 |           : undefined,
 40 |       })
 41 |     }, [])
 42 |   }
 43 |   onFieldReact(pattern, (field) => {
 44 |     field.loading = true
 45 |     fetch('//unpkg.com/china-location/dist/location.json')
 46 |       .then((res) => res.json())
 47 |       .then(
 48 |         action.bound((data) => {
 49 |           field.dataSource = transform(data)
 50 |           field.loading = false
 51 |         })
 52 |       )
 53 |   })
 54 | }
 55 | 
 56 | const form = createForm({
 57 |   effects: () => {
 58 |     useAddress('address')
 59 |   },
 60 | })
 61 | 
 62 | export default () => (
 63 |   <FormProvider form={form}>
 64 |     <SchemaField>
 65 |       <SchemaField.String
 66 |         name="address"
 67 |         title="地址选择"
 68 |         required
 69 |         x-decorator="FormItem"
 70 |         x-component="Cascader"
 71 |         x-component-props={{
 72 |           style: {
 73 |             width: 240,
 74 |           },
 75 |         }}
 76 |       />
 77 |     </SchemaField>
 78 |     <FormButtonGroup>
 79 |       <Submit onSubmit={console.log}>提交</Submit>
 80 |     </FormButtonGroup>
 81 |   </FormProvider>
 82 | )
 83 | ```
 84 | 
 85 | ## JSON Schema 案例
 86 | 
 87 | ```tsx
 88 | import React from 'react'
 89 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 90 | import { createForm } from '@formily/core'
 91 | import { FormProvider, createSchemaField } from '@formily/react'
 92 | import { action } from '@formily/reactive'
 93 | 
 94 | const SchemaField = createSchemaField({
 95 |   components: {
 96 |     Cascader,
 97 |     FormItem,
 98 |   },
 99 | })
100 | 
101 | const transformAddress = (data = {}) => {
102 |   return Object.entries(data).reduce((buf, [key, value]) => {
103 |     if (typeof value === 'string')
104 |       return buf.concat({
105 |         label: value,
106 |         value: key,
107 |       })
108 |     const { name, code, cities, districts } = value
109 |     const _cities = transformAddress(cities)
110 |     const _districts = transformAddress(districts)
111 |     return buf.concat({
112 |       label: name,
113 |       value: code,
114 |       children: _cities.length
115 |         ? _cities
116 |         : _districts.length
117 |         ? _districts
118 |         : undefined,
119 |     })
120 |   }, [])
121 | }
122 | 
123 | const useAsyncDataSource =
124 |   (url: string, transform: (data: any) => any) => (field) => {
125 |     field.loading = true
126 |     fetch(url)
127 |       .then((res) => res.json())
128 |       .then(
129 |         action.bound((data) => {
130 |           field.dataSource = transform(data)
131 |           field.loading = false
132 |         })
133 |       )
134 |   }
135 | 
136 | const form = createForm()
137 | 
138 | const schema = {
139 |   type: 'object',
140 |   properties: {
141 |     address: {
142 |       type: 'string',
143 |       title: '地址选择',
144 |       'x-decorator': 'FormItem',
145 |       'x-component': 'Cascader',
146 |       'x-component-props': {
147 |         style: {
148 |           width: 240,
149 |         },
150 |       },
151 |       'x-reactions': [
152 |         '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}',
153 |       ],
154 |     },
155 |   },
156 | }
157 | 
158 | export default () => (
159 |   <FormProvider form={form}>
160 |     <SchemaField
161 |       schema={schema}
162 |       scope={{ useAsyncDataSource, transformAddress }}
163 |     />
164 |     <FormButtonGroup>
165 |       <Submit onSubmit={console.log}>提交</Submit>
166 |     </FormButtonGroup>
167 |   </FormProvider>
168 | )
169 | ```
170 | 
171 | ## 纯 JSX 案例
172 | 
173 | ```tsx
174 | import React from 'react'
175 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
176 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
177 | import { FormProvider, Field } from '@formily/react'
178 | import { action } from '@formily/reactive'
179 | 
180 | const useAddress = (pattern: FormPathPattern) => {
181 |   const transform = (data = {}) => {
182 |     return Object.entries(data).reduce((buf, [key, value]) => {
183 |       if (typeof value === 'string')
184 |         return buf.concat({
185 |           label: value,
186 |           value: key,
187 |         })
188 |       const { name, code, cities, districts } = value
189 |       const _cities = transform(cities)
190 |       const _districts = transform(districts)
191 |       return buf.concat({
192 |         label: name,
193 |         value: code,
194 |         children: _cities.length
195 |           ? _cities
196 |           : _districts.length
197 |           ? _districts
198 |           : undefined,
199 |       })
200 |     }, [])
201 |   }
202 |   onFieldReact(pattern, (field) => {
203 |     field.loading = true
204 |     fetch('//unpkg.com/china-location/dist/location.json')
205 |       .then((res) => res.json())
206 |       .then(
207 |         action.bound((data) => {
208 |           field.dataSource = transform(data)
209 |           field.loading = false
210 |         })
211 |       )
212 |   })
213 | }
214 | 
215 | const form = createForm({
216 |   effects: () => {
217 |     useAddress('address')
218 |   },
219 | })
220 | 
221 | export default () => (
222 |   <FormProvider form={form}>
223 |     <Field
224 |       name="address"
225 |       title="地址选择"
226 |       decorator={[FormItem]}
227 |       component={[
228 |         Cascader,
229 |         {
230 |           style: {
231 |             width: 240,
232 |           },
233 |         },
234 |       ]}
235 |     />
236 |     <FormButtonGroup>
237 |       <Submit onSubmit={console.log}>提交</Submit>
238 |     </FormButtonGroup>
239 |   </FormProvider>
240 | )
241 | ```
242 | 
243 | ## API
244 | 
245 | 参考 https://ant.design/components/cascader-cn/
246 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/Cascader.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Cascader
  2 | 
  3 | > Cascade selector
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
 10 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | import { action } from '@formily/reactive'
 13 | 
 14 | const SchemaField = createSchemaField({
 15 |   components: {
 16 |     Cascader,
 17 |     FormItem,
 18 |   },
 19 | })
 20 | 
 21 | const useAddress = (pattern: FormPathPattern) => {
 22 |   const transform = (data = {}) => {
 23 |     return Object.entries(data).reduce((buf, [key, value]) => {
 24 |       if (typeof value === 'string')
 25 |         return buf.concat({
 26 |           label: value,
 27 |           value: key,
 28 |         })
 29 |       const { name, code, cities, districts } = value
 30 |       const _cities = transform(cities)
 31 |       const _districts = transform(districts)
 32 |       return buf.concat({
 33 |         label: name,
 34 |         value: code,
 35 |         children: _cities.length
 36 |           ? _cities
 37 |           : _districts.length
 38 |           ? _districts
 39 |           : undefined,
 40 |       })
 41 |     }, [])
 42 |   }
 43 |   onFieldReact(pattern, (field) => {
 44 |     field.loading = true
 45 |     fetch('//unpkg.com/china-location/dist/location.json')
 46 |       .then((res) => res.json())
 47 |       .then(
 48 |         action.bound((data) => {
 49 |           field.dataSource = transform(data)
 50 |           field.loading = false
 51 |         })
 52 |       )
 53 |   })
 54 | }
 55 | 
 56 | const form = createForm({
 57 |   effects: () => {
 58 |     useAddress('address')
 59 |   },
 60 | })
 61 | 
 62 | export default () => (
 63 |   <FormProvider form={form}>
 64 |     <SchemaField>
 65 |       <SchemaField.String
 66 |         name="address"
 67 |         title="Address Selection"
 68 |         x-decorator="FormItem"
 69 |         x-component="Cascader"
 70 |         x-component-props={{
 71 |           style: {
 72 |             width: 240,
 73 |           },
 74 |         }}
 75 |       />
 76 |     </SchemaField>
 77 |     <FormButtonGroup>
 78 |       <Submit onSubmit={console.log}>Submit</Submit>
 79 |     </FormButtonGroup>
 80 |   </FormProvider>
 81 | )
 82 | ```
 83 | 
 84 | ## JSON Schema case
 85 | 
 86 | ```tsx
 87 | import React from 'react'
 88 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
 89 | import { createForm } from '@formily/core'
 90 | import { FormProvider, createSchemaField } from '@formily/react'
 91 | import { action } from '@formily/reactive'
 92 | 
 93 | const SchemaField = createSchemaField({
 94 |   components: {
 95 |     Cascader,
 96 |     FormItem,
 97 |   },
 98 | })
 99 | 
100 | const transformAddress = (data = {}) => {
101 |   return Object.entries(data).reduce((buf, [key, value]) => {
102 |     if (typeof value === 'string')
103 |       return buf.concat({
104 |         label: value,
105 |         value: key,
106 |       })
107 |     const { name, code, cities, districts } = value
108 |     const _cities = transformAddress(cities)
109 |     const _districts = transformAddress(districts)
110 |     return buf.concat({
111 |       label: name,
112 |       value: code,
113 |       children: _cities.length
114 |         ? _cities
115 |         : _districts.length
116 |         ? _districts
117 |         : undefined,
118 |     })
119 |   }, [])
120 | }
121 | 
122 | const useAsyncDataSource =
123 |   (url: string, transform: (data: any) => any) => (field) => {
124 |     field.loading = true
125 |     fetch(url)
126 |       .then((res) => res.json())
127 |       .then(
128 |         action.bound((data) => {
129 |           field.dataSource = transform(data)
130 |           field.loading = false
131 |         })
132 |       )
133 |   }
134 | 
135 | const form = createForm()
136 | 
137 | const schema = {
138 |   type: 'object',
139 |   properties: {
140 |     address: {
141 |       type: 'string',
142 |       title: 'Address Selection',
143 |       'x-decorator': 'FormItem',
144 |       'x-component': 'Cascader',
145 |       'x-component-props': {
146 |         style: {
147 |           width: 240,
148 |         },
149 |       },
150 |       'x-reactions': [
151 |         '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}',
152 |       ],
153 |     },
154 |   },
155 | }
156 | 
157 | export default () => (
158 |   <FormProvider form={form}>
159 |     <SchemaField
160 |       schema={schema}
161 |       scope={{ useAsyncDataSource, transformAddress }}
162 |     />
163 |     <FormButtonGroup>
164 |       <Submit onSubmit={console.log}>Submit</Submit>
165 |     </FormButtonGroup>
166 |   </FormProvider>
167 | )
168 | ```
169 | 
170 | ## Pure JSX case
171 | 
172 | ```tsx
173 | import React from 'react'
174 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'
175 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
176 | import { FormProvider, Field } from '@formily/react'
177 | import { action } from '@formily/reactive'
178 | 
179 | const useAddress = (pattern: FormPathPattern) => {
180 |   const transform = (data = {}) => {
181 |     return Object.entries(data).reduce((buf, [key, value]) => {
182 |       if (typeof value === 'string')
183 |         return buf.concat({
184 |           label: value,
185 |           value: key,
186 |         })
187 |       const { name, code, cities, districts } = value
188 |       const _cities = transform(cities)
189 |       const _districts = transform(districts)
190 |       return buf.concat({
191 |         label: name,
192 |         value: code,
193 |         children: _cities.length
194 |           ? _cities
195 |           : _districts.length
196 |           ? _districts
197 |           : undefined,
198 |       })
199 |     }, [])
200 |   }
201 |   onFieldReact(pattern, (field) => {
202 |     field.loading = true
203 |     fetch('//unpkg.com/china-location/dist/location.json')
204 |       .then((res) => res.json())
205 |       .then(
206 |         action.bound((data) => {
207 |           field.dataSource = transform(data)
208 |           field.loading = false
209 |         })
210 |       )
211 |   })
212 | }
213 | 
214 | const form = createForm({
215 |   effects: () => {
216 |     useAddress('address')
217 |   },
218 | })
219 | 
220 | export default () => (
221 |   <FormProvider form={form}>
222 |     <Field
223 |       name="address"
224 |       title="Address Selection"
225 |       decorator={[FormItem]}
226 |       component={[
227 |         Cascader,
228 |         {
229 |           style: {
230 |             width: 240,
231 |           },
232 |         },
233 |       ]}
234 |     />
235 |     <FormButtonGroup>
236 |       <Submit onSubmit={console.log}>Submit</Submit>
237 |     </FormButtonGroup>
238 |   </FormProvider>
239 | )
240 | ```
241 | 
242 | ## API
243 | 
244 | Reference https://fusion.design/pc/component/basic/cascader-select
245 | 
```

--------------------------------------------------------------------------------
/packages/antd/docs/components/Cascader.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Cascader
  2 | 
  3 | > Cascade selector
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 10 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | import { action } from '@formily/reactive'
 13 | 
 14 | const SchemaField = createSchemaField({
 15 |   components: {
 16 |     Cascader,
 17 |     FormItem,
 18 |   },
 19 | })
 20 | 
 21 | const useAddress = (pattern: FormPathPattern) => {
 22 |   const transform = (data = {}) => {
 23 |     return Object.entries(data).reduce((buf, [key, value]) => {
 24 |       if (typeof value === 'string')
 25 |         return buf.concat({
 26 |           label: value,
 27 |           value: key,
 28 |         })
 29 |       const { name, code, cities, districts } = value
 30 |       const _cities = transform(cities)
 31 |       const _districts = transform(districts)
 32 |       return buf.concat({
 33 |         label: name,
 34 |         value: code,
 35 |         children: _cities.length
 36 |           ? _cities
 37 |           : _districts.length
 38 |           ? _districts
 39 |           : undefined,
 40 |       })
 41 |     }, [])
 42 |   }
 43 |   onFieldReact(pattern, (field) => {
 44 |     field.loading = true
 45 |     fetch('//unpkg.com/china-location/dist/location.json')
 46 |       .then((res) => res.json())
 47 |       .then(
 48 |         action.bound((data) => {
 49 |           field.dataSource = transform(data)
 50 |           field.loading = false
 51 |         })
 52 |       )
 53 |   })
 54 | }
 55 | 
 56 | const form = createForm({
 57 |   effects: () => {
 58 |     useAddress('address')
 59 |   },
 60 | })
 61 | 
 62 | export default () => (
 63 |   <FormProvider form={form}>
 64 |     <SchemaField>
 65 |       <SchemaField.String
 66 |         name="address"
 67 |         title="Address Selection"
 68 |         required
 69 |         x-decorator="FormItem"
 70 |         x-component="Cascader"
 71 |         x-component-props={{
 72 |           style: {
 73 |             width: 240,
 74 |           },
 75 |         }}
 76 |       />
 77 |     </SchemaField>
 78 |     <FormButtonGroup>
 79 |       <Submit onSubmit={console.log}>Submit</Submit>
 80 |     </FormButtonGroup>
 81 |   </FormProvider>
 82 | )
 83 | ```
 84 | 
 85 | ## JSON Schema case
 86 | 
 87 | ```tsx
 88 | import React from 'react'
 89 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 90 | import { createForm } from '@formily/core'
 91 | import { FormProvider, createSchemaField } from '@formily/react'
 92 | import { action } from '@formily/reactive'
 93 | 
 94 | const SchemaField = createSchemaField({
 95 |   components: {
 96 |     Cascader,
 97 |     FormItem,
 98 |   },
 99 | })
100 | 
101 | const transformAddress = (data = {}) => {
102 |   return Object.entries(data).reduce((buf, [key, value]) => {
103 |     if (typeof value === 'string')
104 |       return buf.concat({
105 |         label: value,
106 |         value: key,
107 |       })
108 |     const { name, code, cities, districts } = value
109 |     const _cities = transformAddress(cities)
110 |     const _districts = transformAddress(districts)
111 |     return buf.concat({
112 |       label: name,
113 |       value: code,
114 |       children: _cities.length
115 |         ? _cities
116 |         : _districts.length
117 |         ? _districts
118 |         : undefined,
119 |     })
120 |   }, [])
121 | }
122 | 
123 | const useAsyncDataSource =
124 |   (url: string, transform: (data: any) => any) => (field) => {
125 |     field.loading = true
126 |     fetch(url)
127 |       .then((res) => res.json())
128 |       .then(
129 |         action.bound((data) => {
130 |           field.dataSource = transform(data)
131 |           field.loading = false
132 |         })
133 |       )
134 |   }
135 | 
136 | const form = createForm()
137 | 
138 | const schema = {
139 |   type: 'object',
140 |   properties: {
141 |     address: {
142 |       type: 'string',
143 |       title: 'Address Selection',
144 |       'x-decorator': 'FormItem',
145 |       'x-component': 'Cascader',
146 |       'x-component-props': {
147 |         style: {
148 |           width: 240,
149 |         },
150 |       },
151 |       'x-reactions': [
152 |         '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}',
153 |       ],
154 |     },
155 |   },
156 | }
157 | 
158 | export default () => (
159 |   <FormProvider form={form}>
160 |     <SchemaField
161 |       schema={schema}
162 |       scope={{ useAsyncDataSource, transformAddress }}
163 |     />
164 |     <FormButtonGroup>
165 |       <Submit onSubmit={console.log}>Submit</Submit>
166 |     </FormButtonGroup>
167 |   </FormProvider>
168 | )
169 | ```
170 | 
171 | ## Pure JSX case
172 | 
173 | ```tsx
174 | import React from 'react'
175 | import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'
176 | import { createForm, onFieldReact, FormPathPattern } from '@formily/core'
177 | import { FormProvider, Field } from '@formily/react'
178 | import { action } from '@formily/reactive'
179 | 
180 | const useAddress = (pattern: FormPathPattern) => {
181 |   const transform = (data = {}) => {
182 |     return Object.entries(data).reduce((buf, [key, value]) => {
183 |       if (typeof value === 'string')
184 |         return buf.concat({
185 |           label: value,
186 |           value: key,
187 |         })
188 |       const { name, code, cities, districts } = value
189 |       const _cities = transform(cities)
190 |       const _districts = transform(districts)
191 |       return buf.concat({
192 |         label: name,
193 |         value: code,
194 |         children: _cities.length
195 |           ? _cities
196 |           : _districts.length
197 |           ? _districts
198 |           : undefined,
199 |       })
200 |     }, [])
201 |   }
202 |   onFieldReact(pattern, (field) => {
203 |     field.loading = true
204 |     fetch('//unpkg.com/china-location/dist/location.json')
205 |       .then((res) => res.json())
206 |       .then(
207 |         action.bound((data) => {
208 |           field.dataSource = transform(data)
209 |           field.loading = false
210 |         })
211 |       )
212 |   })
213 | }
214 | 
215 | const form = createForm({
216 |   effects: () => {
217 |     useAddress('address')
218 |   },
219 | })
220 | 
221 | export default () => (
222 |   <FormProvider form={form}>
223 |     <Field
224 |       name="address"
225 |       title="Address Selection"
226 |       decorator={[FormItem]}
227 |       component={[
228 |         Cascader,
229 |         {
230 |           style: {
231 |             width: 240,
232 |           },
233 |         },
234 |       ]}
235 |     />
236 |     <FormButtonGroup>
237 |       <Submit onSubmit={console.log}>Submit</Submit>
238 |     </FormButtonGroup>
239 |   </FormProvider>
240 | )
241 | ```
242 | 
243 | ## API
244 | 
245 | Reference https://ant.design/components/cascader-cn/
246 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/PreviewText.md:
--------------------------------------------------------------------------------

```markdown
  1 | # PreviewText
  2 | 
  3 | > Reading state components, mainly used to implement the reading state of these components of class Input and DatePicker
  4 | 
  5 | ## Simple use case
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { PreviewText, FormItem, FormLayout } from '@formily/next'
 10 | import { createForm } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | 
 13 | const SchemaField = createSchemaField({
 14 |   components: {
 15 |     FormItem,
 16 |     PreviewText,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => {
 23 |   return (
 24 |     <FormLayout labelCol={8} wrapperCol={16}>
 25 |       <FormProvider form={form}>
 26 |         <SchemaField>
 27 |           <SchemaField.String
 28 |             x-decorator="FormItem"
 29 |             title="text preview"
 30 |             x-component="PreviewText.Input"
 31 |             default={'Hello world'}
 32 |           />
 33 |           <SchemaField.String
 34 |             x-decorator="FormItem"
 35 |             title="Select item preview"
 36 |             x-component="PreviewText.Select"
 37 |             x-component-props={{
 38 |               mode: 'multiple',
 39 |             }}
 40 |             default={['123', '222']}
 41 |             enum={[
 42 |               { label: 'A111', value: '123' },
 43 |               { label: 'A222', value: '222' },
 44 |             ]}
 45 |           />
 46 |           <SchemaField.String
 47 |             x-decorator="FormItem"
 48 |             title="date preview"
 49 |             x-component="PreviewText.DatePicker"
 50 |             default={'2020-11-23 22:15:20'}
 51 |           />
 52 |           <SchemaField.String
 53 |             x-decorator="FormItem"
 54 |             title="Cascader Preview"
 55 |             x-component="PreviewText.Cascader"
 56 |             default={'yuhang'}
 57 |             enum={[
 58 |               {
 59 |                 label: 'Hangzhou',
 60 |                 value: 'hangzhou',
 61 |                 children: [
 62 |                   {
 63 |                     label: 'Yuhang',
 64 |                     value: 'yuhang',
 65 |                   },
 66 |                 ],
 67 |               },
 68 |             ]}
 69 |           />
 70 |         </SchemaField>
 71 |       </FormProvider>
 72 |     </FormLayout>
 73 |   )
 74 | }
 75 | ```
 76 | 
 77 | ## Extended reading mode
 78 | 
 79 | ```tsx
 80 | import React from 'react'
 81 | import {
 82 |   PreviewText,
 83 |   FormItem,
 84 |   FormButtonGroup,
 85 |   FormLayout,
 86 | } from '@formily/next'
 87 | import { createForm } from '@formily/core'
 88 | import {
 89 |   FormProvider,
 90 |   mapReadPretty,
 91 |   connect,
 92 |   createSchemaField,
 93 | } from '@formily/react'
 94 | import { Button, Input as NextInput } from '@alifd/next'
 95 | 
 96 | const Input = connect(NextInput, mapReadPretty(PreviewText.Input))
 97 | 
 98 | const SchemaField = createSchemaField({
 99 |   components: {
100 |     Input,
101 |     FormItem,
102 |     PreviewText,
103 |   },
104 | })
105 | 
106 | const form = createForm()
107 | 
108 | export default () => {
109 |   return (
110 |     <PreviewText.Placeholder value="No data currently available">
111 |       <FormLayout labelCol={8} wrapperCol={16}>
112 |         <FormProvider form={form}>
113 |           <SchemaField>
114 |             <SchemaField.Markup
115 |               type="string"
116 |               x-decorator="FormItem"
117 |               title="text preview"
118 |               required
119 |               x-component="Input"
120 |               default={'Hello world'}
121 |             />
122 |             <SchemaField.Markup
123 |               type="string"
124 |               x-decorator="FormItem"
125 |               title="Select item preview"
126 |               x-component="PreviewText.Select"
127 |               x-component-props={{
128 |                 mode: 'multiple',
129 |               }}
130 |               default={['123']}
131 |               enum={[
132 |                 { label: 'A111', value: '123' },
133 |                 { label: 'A222', value: '222' },
134 |               ]}
135 |             />
136 |             <SchemaField.Markup
137 |               type="string"
138 |               x-decorator="FormItem"
139 |               title="date preview"
140 |               x-component="PreviewText.DatePicker"
141 |             />
142 |             <SchemaField.Markup
143 |               type="string"
144 |               x-decorator="FormItem"
145 |               title="Cascader Preview"
146 |               x-component="PreviewText.Cascader"
147 |               default={'yuhang'}
148 |               enum={[
149 |                 {
150 |                   label: 'Hangzhou',
151 |                   value: 'hangzhou',
152 |                   children: [
153 |                     {
154 |                       label: 'Yuhang',
155 |                       value: 'yuhang',
156 |                     },
157 |                   ],
158 |                 },
159 |               ]}
160 |             />
161 |           </SchemaField>
162 |           <FormButtonGroup.FormItem>
163 |             <Button
164 |               onClick={() => {
165 |                 form.setState((state) => {
166 |                   state.editable = !state.editable
167 |                 })
168 |               }}
169 |             >
170 |               Switch reading mode
171 |             </Button>
172 |           </FormButtonGroup.FormItem>
173 |         </FormProvider>
174 |       </FormLayout>
175 |     </PreviewText.Placeholder>
176 |   )
177 | }
178 | ```
179 | 
180 | ## API
181 | 
182 | ### PreviewText.Input
183 | 
184 | Reference https://fusion.design/pc/component/basic/input
185 | 
186 | ### PreviewText.Select
187 | 
188 | Reference https://fusion.design/pc/component/basic/select
189 | 
190 | ### PreviewText.TreeSelect
191 | 
192 | Reference https://fusion.design/pc/component/basic/tree-select
193 | 
194 | ### PreviewText.Cascader
195 | 
196 | Reference https://fusion.design/pc/component/basic/cascader-select
197 | 
198 | ### PreviewText.DatePicker
199 | 
200 | Reference https://fusion.design/pc/component/basic/date-picker
201 | 
202 | ### PreviewText.DateRangePicker
203 | 
204 | Reference https://fusion.design/pc/component/basic/date-picker
205 | 
206 | ### PreviewText.TimePicker
207 | 
208 | Reference https://fusion.design/pc/component/basic/time-picker
209 | 
210 | ### PreviewText.NumberPicker
211 | 
212 | Reference https://fusion.design/pc/component/basic/number-picker
213 | 
214 | ### PreviewText.Placeholder
215 | 
216 | | Property name | Type   | Description         | Default value |
217 | | ------------- | ------ | ------------------- | ------------- |
218 | | value         | stirng | Default placeholder | N/A           |
219 | 
220 | ### PreviewText.usePlaceholder
221 | 
222 | ```ts pure
223 | interface usePlaceholder {
224 |   (): string
225 | }
226 | ```
227 | 
```

--------------------------------------------------------------------------------
/packages/json-schema/src/types.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   IGeneralFieldState,
  3 |   GeneralField,
  4 |   FormPathPattern,
  5 | } from '@formily/core'
  6 | export type SchemaEnum<Message> = Array<
  7 |   | string
  8 |   | number
  9 |   | boolean
 10 |   | { label?: Message; value?: any; [key: string]: any }
 11 |   | { key?: any; title?: Message; [key: string]: any }
 12 | >
 13 | 
 14 | export type SchemaTypes =
 15 |   | 'string'
 16 |   | 'object'
 17 |   | 'array'
 18 |   | 'number'
 19 |   | 'boolean'
 20 |   | 'void'
 21 |   | 'date'
 22 |   | 'datetime'
 23 |   | (string & {})
 24 | 
 25 | export type SchemaProperties<
 26 |   Decorator,
 27 |   Component,
 28 |   DecoratorProps,
 29 |   ComponentProps,
 30 |   Pattern,
 31 |   Display,
 32 |   Validator,
 33 |   Message
 34 | > = Record<
 35 |   string,
 36 |   ISchema<
 37 |     Decorator,
 38 |     Component,
 39 |     DecoratorProps,
 40 |     ComponentProps,
 41 |     Pattern,
 42 |     Display,
 43 |     Validator,
 44 |     Message
 45 |   >
 46 | >
 47 | 
 48 | export type SchemaPatch = (schema: ISchema) => ISchema
 49 | 
 50 | export type SchemaKey = string | number
 51 | 
 52 | export type SchemaEffectTypes =
 53 |   | 'onFieldInit'
 54 |   | 'onFieldMount'
 55 |   | 'onFieldUnmount'
 56 |   | 'onFieldValueChange'
 57 |   | 'onFieldInputValueChange'
 58 |   | 'onFieldInitialValueChange'
 59 |   | 'onFieldValidateStart'
 60 |   | 'onFieldValidateEnd'
 61 |   | 'onFieldValidateFailed'
 62 |   | 'onFieldValidateSuccess'
 63 | 
 64 | export type SchemaReaction<Field = any> =
 65 |   | {
 66 |       dependencies?:
 67 |         | Array<
 68 |             | string
 69 |             | {
 70 |                 name?: string
 71 |                 type?: string
 72 |                 source?: string
 73 |                 property?: string
 74 |               }
 75 |           >
 76 |         | Record<string, string>
 77 |       when?: string | boolean
 78 |       target?: string
 79 |       effects?: (SchemaEffectTypes | (string & {}))[]
 80 |       fulfill?: {
 81 |         state?: Stringify<IGeneralFieldState>
 82 |         schema?: ISchema
 83 |         run?: string
 84 |       }
 85 |       otherwise?: {
 86 |         state?: Stringify<IGeneralFieldState>
 87 |         schema?: ISchema
 88 |         run?: string
 89 |       }
 90 |       [key: string]: any
 91 |     }
 92 |   | ((field: Field, scope: IScopeContext) => void)
 93 | 
 94 | export type SchemaReactions<Field = any> =
 95 |   | SchemaReaction<Field>
 96 |   | SchemaReaction<Field>[]
 97 | 
 98 | export type SchemaItems<
 99 |   Decorator,
100 |   Component,
101 |   DecoratorProps,
102 |   ComponentProps,
103 |   Pattern,
104 |   Display,
105 |   Validator,
106 |   Message
107 | > =
108 |   | ISchema<
109 |       Decorator,
110 |       Component,
111 |       DecoratorProps,
112 |       ComponentProps,
113 |       Pattern,
114 |       Display,
115 |       Validator,
116 |       Message
117 |     >
118 |   | ISchema<
119 |       Decorator,
120 |       Component,
121 |       DecoratorProps,
122 |       ComponentProps,
123 |       Pattern,
124 |       Display,
125 |       Validator,
126 |       Message
127 |     >[]
128 | 
129 | export type SchemaComponents = Record<string, any>
130 | 
131 | export interface ISchemaFieldUpdateRequest {
132 |   state?: Stringify<IGeneralFieldState>
133 |   schema?: ISchema
134 |   run?: string
135 | }
136 | 
137 | export interface IScopeContext {
138 |   [key: string]: any
139 | }
140 | 
141 | export interface IFieldStateSetterOptions {
142 |   field: GeneralField
143 |   target?: FormPathPattern
144 |   request: ISchemaFieldUpdateRequest
145 |   runner?: string
146 |   scope?: IScopeContext
147 | }
148 | 
149 | export interface ISchemaTransformerOptions {
150 |   scope?: IScopeContext
151 | }
152 | 
153 | export type Slot = {
154 |   target: string
155 |   isRenderProp?: boolean
156 | }
157 | 
158 | export type Stringify<P extends { [key: string]: any }> = {
159 |   /**
160 |    * Use `string & {}` instead of string to keep Literal Type for ISchema#component and ISchema#decorator
161 |    */
162 |   [key in keyof P]?: P[key] | (string & {})
163 | }
164 | 
165 | export type ISchema<
166 |   Decorator = any,
167 |   Component = any,
168 |   DecoratorProps = any,
169 |   ComponentProps = any,
170 |   Pattern = any,
171 |   Display = any,
172 |   Validator = any,
173 |   Message = any,
174 |   ReactionField = any
175 | > = Stringify<{
176 |   version?: string
177 |   name?: SchemaKey
178 |   title?: Message
179 |   description?: Message
180 |   default?: any
181 |   readOnly?: boolean
182 |   writeOnly?: boolean
183 |   type?: SchemaTypes
184 |   enum?: SchemaEnum<Message>
185 |   const?: any
186 |   multipleOf?: number
187 |   maximum?: number
188 |   exclusiveMaximum?: number
189 |   minimum?: number
190 |   exclusiveMinimum?: number
191 |   maxLength?: number
192 |   minLength?: number
193 |   pattern?: string | RegExp
194 |   maxItems?: number
195 |   minItems?: number
196 |   uniqueItems?: boolean
197 |   maxProperties?: number
198 |   minProperties?: number
199 |   required?: string[] | boolean | string
200 |   format?: string
201 |   $ref?: string
202 |   $namespace?: string
203 |   /** nested json schema spec **/
204 |   definitions?: SchemaProperties<
205 |     Decorator,
206 |     Component,
207 |     DecoratorProps,
208 |     ComponentProps,
209 |     Pattern,
210 |     Display,
211 |     Validator,
212 |     Message
213 |   >
214 |   properties?: SchemaProperties<
215 |     Decorator,
216 |     Component,
217 |     DecoratorProps,
218 |     ComponentProps,
219 |     Pattern,
220 |     Display,
221 |     Validator,
222 |     Message
223 |   >
224 |   items?: SchemaItems<
225 |     Decorator,
226 |     Component,
227 |     DecoratorProps,
228 |     ComponentProps,
229 |     Pattern,
230 |     Display,
231 |     Validator,
232 |     Message
233 |   >
234 |   additionalItems?: ISchema<
235 |     Decorator,
236 |     Component,
237 |     DecoratorProps,
238 |     ComponentProps,
239 |     Pattern,
240 |     Display,
241 |     Validator,
242 |     Message
243 |   >
244 |   patternProperties?: SchemaProperties<
245 |     Decorator,
246 |     Component,
247 |     DecoratorProps,
248 |     ComponentProps,
249 |     Pattern,
250 |     Display,
251 |     Validator,
252 |     Message
253 |   >
254 |   additionalProperties?: ISchema<
255 |     Decorator,
256 |     Component,
257 |     DecoratorProps,
258 |     ComponentProps,
259 |     Pattern,
260 |     Display,
261 |     Validator,
262 |     Message
263 |   >
264 | 
265 |   ['x-value']?: any
266 | 
267 |   //顺序描述
268 |   ['x-index']?: number
269 |   //交互模式
270 |   ['x-pattern']?: Pattern
271 |   //展示状态
272 |   ['x-display']?: Display
273 |   //校验器
274 |   ['x-validator']?: Validator
275 |   //装饰器
276 |   ['x-decorator']?: Decorator | (string & {}) | ((...args: any[]) => any)
277 |   //装饰器属性
278 |   ['x-decorator-props']?: DecoratorProps
279 |   //组件
280 |   ['x-component']?: Component | (string & {}) | ((...args: any[]) => any)
281 |   //组件属性
282 |   ['x-component-props']?: ComponentProps
283 |   //组件响应器
284 |   ['x-reactions']?: SchemaReactions<ReactionField>
285 |   //内容
286 |   ['x-content']?: any
287 | 
288 |   ['x-data']?: any
289 | 
290 |   ['x-visible']?: boolean
291 | 
292 |   ['x-hidden']?: boolean
293 | 
294 |   ['x-disabled']?: boolean
295 | 
296 |   ['x-editable']?: boolean
297 | 
298 |   ['x-read-only']?: boolean
299 | 
300 |   ['x-read-pretty']?: boolean
301 | 
302 |   ['x-compile-omitted']?: string[]
303 | 
304 |   [key: `x-${string | number}` | symbol]: any
305 | }>
306 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/array-items/json-schema.vue:
--------------------------------------------------------------------------------

```vue
  1 | <template>
  2 |   <FormProvider :form="form">
  3 |     <SchemaField :schema="schema" />
  4 |     <Submit @submit="log">提交</Submit>
  5 |   </FormProvider>
  6 | </template>
  7 | 
  8 | <script>
  9 | import { createForm } from '@formily/core'
 10 | import { FormProvider, createSchemaField } from '@formily/vue'
 11 | import {
 12 |   FormButtonGroup,
 13 |   Submit,
 14 |   FormItem,
 15 |   Space,
 16 |   Input,
 17 |   Select,
 18 |   DatePicker,
 19 |   ArrayItems,
 20 | } from '@formily/element'
 21 | import { Button } from 'element-ui'
 22 | 
 23 | const SchemaField = createSchemaField({
 24 |   components: {
 25 |     FormItem,
 26 |     Space,
 27 |     Input,
 28 |     Select,
 29 |     DatePicker,
 30 |     ArrayItems,
 31 |   },
 32 | })
 33 | 
 34 | export default {
 35 |   components: {
 36 |     FormProvider,
 37 |     FormButtonGroup,
 38 |     Button,
 39 |     Submit,
 40 |     ...SchemaField,
 41 |   },
 42 | 
 43 |   data() {
 44 |     const form = createForm()
 45 |     const schema = {
 46 |       type: 'object',
 47 |       properties: {
 48 |         string_array: {
 49 |           type: 'array',
 50 |           'x-component': 'ArrayItems',
 51 |           'x-decorator': 'FormItem',
 52 |           title: '字符串数组',
 53 |           items: {
 54 |             type: 'void',
 55 |             'x-component': 'Space',
 56 |             properties: {
 57 |               sort: {
 58 |                 type: 'void',
 59 |                 'x-decorator': 'FormItem',
 60 |                 'x-component': 'ArrayItems.SortHandle',
 61 |               },
 62 |               input: {
 63 |                 type: 'string',
 64 |                 'x-decorator': 'FormItem',
 65 |                 'x-component': 'Input',
 66 |               },
 67 |               remove: {
 68 |                 type: 'void',
 69 |                 'x-decorator': 'FormItem',
 70 |                 'x-component': 'ArrayItems.Remove',
 71 |               },
 72 |             },
 73 |           },
 74 |           properties: {
 75 |             add: {
 76 |               type: 'void',
 77 |               title: '添加条目',
 78 |               'x-component': 'ArrayItems.Addition',
 79 |             },
 80 |           },
 81 |         },
 82 |         array: {
 83 |           type: 'array',
 84 |           'x-component': 'ArrayItems',
 85 |           'x-decorator': 'FormItem',
 86 |           title: '对象数组',
 87 |           items: {
 88 |             type: 'object',
 89 |             properties: {
 90 |               space: {
 91 |                 type: 'void',
 92 |                 'x-component': 'Space',
 93 |                 properties: {
 94 |                   sort: {
 95 |                     type: 'void',
 96 |                     'x-decorator': 'FormItem',
 97 |                     'x-component': 'ArrayItems.SortHandle',
 98 |                   },
 99 |                   date: {
100 |                     type: 'string',
101 |                     title: '日期',
102 |                     'x-decorator': 'FormItem',
103 |                     'x-component': 'DatePicker',
104 |                     'x-component-props': {
105 |                       type: 'daterange',
106 |                       style: {
107 |                         width: '250px',
108 |                       },
109 |                     },
110 |                   },
111 |                   input: {
112 |                     type: 'string',
113 |                     title: '输入框',
114 |                     'x-decorator': 'FormItem',
115 |                     'x-component': 'Input',
116 |                   },
117 |                   select: {
118 |                     type: 'string',
119 |                     title: '下拉框',
120 |                     enum: [
121 |                       { label: '选项1', value: 1 },
122 |                       { label: '选项2', value: 2 },
123 |                     ],
124 |                     'x-decorator': 'FormItem',
125 |                     'x-component': 'Select',
126 |                     'x-component-props': {
127 |                       style: {
128 |                         width: '250px',
129 |                       },
130 |                     },
131 |                   },
132 |                   remove: {
133 |                     type: 'void',
134 |                     'x-decorator': 'FormItem',
135 |                     'x-component': 'ArrayItems.Remove',
136 |                   },
137 |                 },
138 |               },
139 |             },
140 |           },
141 |           properties: {
142 |             add: {
143 |               type: 'void',
144 |               title: '添加条目',
145 |               'x-component': 'ArrayItems.Addition',
146 |             },
147 |           },
148 |         },
149 |         array2: {
150 |           type: 'array',
151 |           'x-component': 'ArrayItems',
152 |           'x-decorator': 'FormItem',
153 |           'x-component-props': { style: { width: '600px' } },
154 |           title: '对象数组',
155 |           items: {
156 |             type: 'object',
157 |             'x-decorator': 'ArrayItems.Item',
158 |             properties: {
159 |               space: {
160 |                 type: 'void',
161 |                 'x-component': 'Space',
162 |                 properties: {
163 |                   sort: {
164 |                     type: 'void',
165 |                     'x-decorator': 'FormItem',
166 |                     'x-component': 'ArrayItems.SortHandle',
167 |                   },
168 |                   date: {
169 |                     type: 'string',
170 |                     title: '日期',
171 |                     'x-decorator': 'FormItem',
172 |                     'x-component': 'DatePicker',
173 |                     'x-component-props': {
174 |                       type: 'daterange',
175 |                       style: {
176 |                         width: '250px',
177 |                       },
178 |                     },
179 |                   },
180 |                   input: {
181 |                     type: 'string',
182 |                     title: '输入框',
183 |                     'x-decorator': 'FormItem',
184 |                     'x-component': 'Input',
185 |                   },
186 |                   remove: {
187 |                     type: 'void',
188 |                     'x-decorator': 'FormItem',
189 |                     'x-component': 'ArrayItems.Remove',
190 |                   },
191 |                 },
192 |               },
193 |             },
194 |           },
195 |           properties: {
196 |             add: {
197 |               type: 'void',
198 |               title: '添加条目',
199 |               'x-component': 'ArrayItems.Addition',
200 |             },
201 |           },
202 |         },
203 |       },
204 |     }
205 | 
206 |     return {
207 |       form,
208 |       schema,
209 |     }
210 |   },
211 |   methods: {
212 |     log(values) {
213 |       console.log(values)
214 |     },
215 |   },
216 | }
217 | </script>
218 | 
219 | <style lang="scss" scoped></style>
220 | 
```

--------------------------------------------------------------------------------
/packages/antd/docs/components/FormTab.md:
--------------------------------------------------------------------------------

```markdown
  1 | # FormTab
  2 | 
  3 | > Tab form
  4 | >
  5 | > Note: This component is only applicable to Schema scenarios
  6 | 
  7 | ## Markup Schema example
  8 | 
  9 | ```tsx
 10 | import React from 'react'
 11 | import {
 12 |   FormTab,
 13 |   FormItem,
 14 |   Input,
 15 |   FormButtonGroup,
 16 |   Submit,
 17 | } from '@formily/antd'
 18 | import { createForm } from '@formily/core'
 19 | import { FormProvider, createSchemaField } from '@formily/react'
 20 | import { Button } from 'antd'
 21 | 
 22 | const SchemaField = createSchemaField({
 23 |   components: {
 24 |     FormItem,
 25 |     FormTab,
 26 |     Input,
 27 |   },
 28 | })
 29 | 
 30 | const form = createForm()
 31 | const formTab = FormTab.createFormTab()
 32 | 
 33 | export default () => {
 34 |   return (
 35 |     <FormProvider form={form}>
 36 |       <SchemaField>
 37 |         <SchemaField.Void
 38 |           type="void"
 39 |           x-component="FormTab"
 40 |           x-component-props={{ formTab }}
 41 |         >
 42 |           <SchemaField.Void
 43 |             type="void"
 44 |             name="tab1"
 45 |             x-component="FormTab.TabPane"
 46 |             x-component-props={{ tab: 'A1' }}
 47 |           >
 48 |             <SchemaField.String
 49 |               name="aaa"
 50 |               x-decorator="FormItem"
 51 |               title="AAA"
 52 |               required
 53 |               x-component="Input"
 54 |             />
 55 |           </SchemaField.Void>
 56 |           <SchemaField.Void
 57 |             name="tab2"
 58 |             x-component="FormTab.TabPane"
 59 |             x-component-props={{ tab: 'A2' }}
 60 |           >
 61 |             <SchemaField.String
 62 |               name="bbb"
 63 |               x-decorator="FormItem"
 64 |               title="BBB"
 65 |               required
 66 |               x-component="Input"
 67 |             />
 68 |           </SchemaField.Void>
 69 |           <SchemaField.Void
 70 |             name="tab3"
 71 |             x-component="FormTab.TabPane"
 72 |             x-component-props={{ tab: 'A3' }}
 73 |           >
 74 |             <SchemaField.String
 75 |               name="ccc"
 76 |               x-decorator="FormItem"
 77 |               title="CCC"
 78 |               required
 79 |               x-component="Input"
 80 |             />
 81 |           </SchemaField.Void>
 82 |         </SchemaField.Void>
 83 |       </SchemaField>
 84 |       <FormButtonGroup.FormItem>
 85 |         <Button
 86 |           onClick={() => {
 87 |             form.query('tab3').take((field) => {
 88 |               field.visible = !field.visible
 89 |             })
 90 |           }}
 91 |         >
 92 |           Show/hide the last tab
 93 |         </Button>
 94 |         <Button
 95 |           onClick={() => {
 96 |             formTab.setActiveKey('tab2')
 97 |           }}
 98 |         >
 99 |           Switch to the second Tab
100 |         </Button>
101 |         <Submit onSubmit={console.log}>Submit</Submit>
102 |       </FormButtonGroup.FormItem>
103 |     </FormProvider>
104 |   )
105 | }
106 | ```
107 | 
108 | ## JSON Schema case
109 | 
110 | ```tsx
111 | import React from 'react'
112 | import {
113 |   FormTab,
114 |   FormItem,
115 |   Input,
116 |   FormButtonGroup,
117 |   Submit,
118 | } from '@formily/antd'
119 | import { createForm } from '@formily/core'
120 | import { FormProvider, createSchemaField } from '@formily/react'
121 | import { Button } from 'antd'
122 | 
123 | const SchemaField = createSchemaField({
124 |   components: {
125 |     FormItem,
126 |     FormTab,
127 |     Input,
128 |   },
129 | })
130 | 
131 | const form = createForm()
132 | const formTab = FormTab.createFormTab()
133 | 
134 | const schema = {
135 |   type: 'object',
136 |   properties: {
137 |     collapse: {
138 |       type: 'void',
139 |       'x-component': 'FormTab',
140 |       'x-component-props': {
141 |         formTab: '{{formTab}}',
142 |       },
143 |       properties: {
144 |         tab1: {
145 |           type: 'void',
146 |           'x-component': 'FormTab.TabPane',
147 |           'x-component-props': {
148 |             tab: 'A1',
149 |           },
150 |           properties: {
151 |             aaa: {
152 |               type: 'string',
153 |               title: 'AAA',
154 |               'x-decorator': 'FormItem',
155 |               required: true,
156 |               'x-component': 'Input',
157 |             },
158 |           },
159 |         },
160 |         tab2: {
161 |           type: 'void',
162 |           'x-component': 'FormTab.TabPane',
163 |           'x-component-props': {
164 |             tab: 'A2',
165 |           },
166 |           properties: {
167 |             bbb: {
168 |               type: 'string',
169 |               title: 'BBB',
170 |               'x-decorator': 'FormItem',
171 |               required: true,
172 |               'x-component': 'Input',
173 |             },
174 |           },
175 |         },
176 |         tab3: {
177 |           type: 'void',
178 |           'x-component': 'FormTab.TabPane',
179 |           'x-component-props': {
180 |             tab: 'A3',
181 |           },
182 |           properties: {
183 |             ccc: {
184 |               type: 'string',
185 |               title: 'CCC',
186 |               'x-decorator': 'FormItem',
187 |               required: true,
188 |               'x-component': 'Input',
189 |             },
190 |           },
191 |         },
192 |       },
193 |     },
194 |   },
195 | }
196 | 
197 | export default () => {
198 |   return (
199 |     <FormProvider form={form}>
200 |       <SchemaField schema={schema} scope={{ formTab }} />
201 |       <FormButtonGroup.FormItem>
202 |         <Button
203 |           onClick={() => {
204 |             form.query('tab3').take((field) => {
205 |               field.visible = !field.visible
206 |             })
207 |           }}
208 |         >
209 |           Show/hide the last tab
210 |         </Button>
211 |         <Button
212 |           onClick={() => {
213 |             formTab.setActiveKey('tab2')
214 |           }}
215 |         >
216 |           Switch to the second Tab
217 |         </Button>
218 |         <Submit onSubmit={console.log}>Submit</Submit>
219 |       </FormButtonGroup.FormItem>
220 |     </FormProvider>
221 |   )
222 | }
223 | ```
224 | 
225 | ## API
226 | 
227 | ### FormTab
228 | 
229 | | Property name | Type     | Description                                           | Default value |
230 | | ------------- | -------- | ----------------------------------------------------- | ------------- |
231 | | formTab       | IFormTab | Pass in the model created by createFormTab/useFormTab |               |
232 | 
233 | Other references https://ant.design/components/tabs-cn/
234 | 
235 | ### FormTab.TabPane
236 | 
237 | Reference https://ant.design/components/tabs-cn/
238 | 
239 | ### FormTab.createFormTab
240 | 
241 | ```ts pure
242 | type ActiveKey = string | number
243 | 
244 | interface createFormTab {
245 |   (defaultActiveKey?: ActiveKey): IFormTab
246 | }
247 | 
248 | interface IFormTab {
249 |   //Activate the primary key
250 |   activeKey: ActiveKey
251 |   //Set the activation key
252 |   setActiveKey(key: ActiveKey): void
253 | }
254 | ```
255 | 
```

--------------------------------------------------------------------------------
/packages/path/src/matcher.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   Segments,
  3 |   Node,
  4 |   isIdentifier,
  5 |   isExpandOperator,
  6 |   isWildcardOperator,
  7 |   isGroupExpression,
  8 |   isRangeExpression,
  9 |   isIgnoreExpression,
 10 |   isDotOperator,
 11 |   isDestructorExpression,
 12 |   IdentifierNode,
 13 |   IgnoreExpressionNode,
 14 |   DestructorExpressionNode,
 15 |   ExpandOperatorNode,
 16 |   WildcardOperatorNode,
 17 |   GroupExpressionNode,
 18 |   RangeExpressionNode,
 19 | } from './types'
 20 | import { isEqual, toArr, isSegmentEqual } from './shared'
 21 | export interface IRecord {
 22 |   score: number
 23 | }
 24 | 
 25 | export class Matcher {
 26 |   private tree: Node
 27 | 
 28 |   private stack: Node[]
 29 | 
 30 |   private record: IRecord
 31 | 
 32 |   private excluding: boolean
 33 | 
 34 |   private wildcards: WildcardOperatorNode[]
 35 | 
 36 |   private path: Segments
 37 | 
 38 |   constructor(tree: Node, record?: any) {
 39 |     this.tree = tree
 40 |     this.stack = []
 41 |     this.excluding = false
 42 |     this.wildcards = []
 43 |     this.record = record
 44 |   }
 45 | 
 46 |   next(node: Node, pos: number) {
 47 |     //  const isOverToken = pos > this.path.length
 48 |     if (node.after) {
 49 |       // if (isOverToken) {
 50 |       //   return false
 51 |       // }
 52 |       return this.matchNode(node.after, pos)
 53 |     }
 54 | 
 55 |     if (isWildcardOperator(node) && !node.filter) {
 56 |       if (this.excluding) {
 57 |         return false
 58 |       } else {
 59 |         if (pos === 0 || node.optional) return true
 60 |         return !!this.take(pos)
 61 |       }
 62 |     }
 63 | 
 64 |     const isLastToken = pos === this.path.length - 1
 65 |     if (isLastToken) {
 66 |       return !!this.take(pos)
 67 |     } else {
 68 |       const wildcard = this.wildcards.pop()
 69 |       if (wildcard && wildcard.after) {
 70 |         return this.next(wildcard, pos)
 71 |       }
 72 |     }
 73 | 
 74 |     return false
 75 |   }
 76 | 
 77 |   shot() {
 78 |     if (this.record?.score >= 0) {
 79 |       this.record.score++
 80 |     }
 81 |   }
 82 | 
 83 |   take(pos: number) {
 84 |     return String(this.path[pos] ?? '')
 85 |   }
 86 | 
 87 |   matchExcludeIdentifier(matched: boolean, node: Node, pos: number) {
 88 |     const isLastToken = pos === this.path.length - 1
 89 |     const isContainToken = pos < this.path.length
 90 |     if (!node.after) {
 91 |       this.excluding = false
 92 |     }
 93 |     if (matched) {
 94 |       if (node.after) {
 95 |         return this.next(node, pos)
 96 |       }
 97 |       if (isLastToken) {
 98 |         return false
 99 |       }
100 |     }
101 |     if (isLastToken) {
102 |       return true
103 |     }
104 |     return isContainToken
105 |   }
106 | 
107 |   matchIdentifier(node: IdentifierNode, pos: number) {
108 |     const current = this.take(pos)
109 |     let matched = false
110 |     if (isExpandOperator(node.after)) {
111 |       if (current.indexOf(node.value) === 0) {
112 |         this.shot()
113 |         matched = true
114 |       }
115 |       if (this.excluding) {
116 |         return this.matchExcludeIdentifier(matched, node.after, pos)
117 |       } else {
118 |         return matched && this.next(node.after, pos)
119 |       }
120 |     } else if (current === node.value) {
121 |       this.shot()
122 |       matched = true
123 |     }
124 |     if (this.excluding) {
125 |       return this.matchExcludeIdentifier(matched, node, pos)
126 |     } else {
127 |       return matched && this.next(node, pos)
128 |     }
129 |   }
130 | 
131 |   matchIgnoreExpression(node: IgnoreExpressionNode, pos: number) {
132 |     return isEqual(node.value, this.take(pos)) && this.next(node, pos)
133 |   }
134 | 
135 |   matchDestructorExpression(node: DestructorExpressionNode, pos: number) {
136 |     return isEqual(node.source, this.take(pos)) && this.next(node, pos)
137 |   }
138 | 
139 |   matchExpandOperator(node: ExpandOperatorNode, pos: number) {
140 |     return this.next(node, pos)
141 |   }
142 | 
143 |   matchWildcardOperator(node: WildcardOperatorNode, pos: number) {
144 |     let matched = false
145 |     if (node.filter) {
146 |       this.stack.push(node)
147 |       matched = this.matchNode(node.filter, pos)
148 |       this.stack.pop()
149 |     } else {
150 |       matched = this.next(node, pos)
151 |     }
152 |     return matched
153 |   }
154 | 
155 |   matchGroupExpression(node: GroupExpressionNode, pos: number) {
156 |     let excluding = false
157 |     if (node.isExclude) {
158 |       excluding = !this.excluding
159 |     }
160 |     return toArr(node.value)[excluding ? 'every' : 'some']((item) => {
161 |       this.wildcards = this.stack.slice() as WildcardOperatorNode[]
162 |       this.excluding = excluding
163 |       return this.matchNode(item, pos)
164 |     })
165 |   }
166 | 
167 |   matchRangeExpression(node: RangeExpressionNode, pos: number) {
168 |     const current = Number(this.take(pos))
169 |     if (node.start) {
170 |       if (node.end) {
171 |         return (
172 |           current >= Number(node.start.value) &&
173 |           current <= Number(node.end.value)
174 |         )
175 |       } else {
176 |         return current >= Number(node.start.value)
177 |       }
178 |     } else {
179 |       if (node.end) {
180 |         return current <= Number(node.end.value)
181 |       } else {
182 |         this.wildcards = this.stack.slice() as WildcardOperatorNode[]
183 |         return this.next(node, pos)
184 |       }
185 |     }
186 |   }
187 | 
188 |   matchNode(node: Node, pos = 0) {
189 |     if (isDotOperator(node)) {
190 |       return this.next(node, pos + 1)
191 |     } else if (isIdentifier(node)) {
192 |       return this.matchIdentifier(node, pos)
193 |     } else if (isIgnoreExpression(node)) {
194 |       return this.matchIgnoreExpression(node, pos)
195 |     } else if (isDestructorExpression(node)) {
196 |       return this.matchDestructorExpression(node, pos)
197 |     } else if (isExpandOperator(node)) {
198 |       return this.matchExpandOperator(node, pos)
199 |     } else if (isWildcardOperator(node)) {
200 |       return this.matchWildcardOperator(node, pos)
201 |     } else if (isGroupExpression(node)) {
202 |       return this.matchGroupExpression(node, pos)
203 |     } else if (isRangeExpression(node)) {
204 |       return this.matchRangeExpression(node, pos)
205 |     }
206 |     return false
207 |   }
208 | 
209 |   match(path: Segments) {
210 |     this.path = path
211 |     return { matched: this.matchNode(this.tree), record: this.record }
212 |   }
213 | 
214 |   static matchSegments(source: Segments, target: Segments, record?: any) {
215 |     if (source.length !== target.length) return { matched: false, record }
216 |     const match = (pos = 0) => {
217 |       const current = isSegmentEqual(source[pos], target[pos])
218 |       if (record?.score >= 0) {
219 |         record.score++
220 |       }
221 |       return current && (pos < source.length - 1 ? match(pos + 1) : true)
222 |     }
223 |     return { matched: match(), record }
224 |   }
225 | }
226 | 
```

--------------------------------------------------------------------------------
/packages/vue/src/components/RecursionField.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { inject, provide, watch, shallowRef, computed, markRaw } from 'vue-demi'
  2 | import { GeneralField } from '@formily/core'
  3 | import { isFn, isValid, lazyMerge } from '@formily/shared'
  4 | import { Schema } from '@formily/json-schema'
  5 | import {
  6 |   SchemaSymbol,
  7 |   SchemaOptionsSymbol,
  8 |   SchemaExpressionScopeSymbol,
  9 | } from '../shared'
 10 | import { useField } from '../hooks'
 11 | import ObjectField from './ObjectField'
 12 | import ArrayField from './ArrayField'
 13 | import Field from './Field'
 14 | import VoidField from './VoidField'
 15 | import { h } from '../shared/h'
 16 | 
 17 | import type { IRecursionFieldProps, DefineComponent } from '../types'
 18 | 
 19 | const resolveEmptySlot = (slots: Record<any, (...args: any[]) => any[]>) => {
 20 |   return Object.keys(slots).length
 21 |     ? h('div', { style: 'display:contents;' }, slots)
 22 |     : undefined
 23 | }
 24 | 
 25 | const RecursionField = {
 26 |   name: 'RecursionField',
 27 |   inheritAttrs: false,
 28 |   props: {
 29 |     schema: {
 30 |       required: true,
 31 |     },
 32 |     name: [String, Number],
 33 |     basePath: {},
 34 |     onlyRenderProperties: {
 35 |       type: Boolean,
 36 |       default: undefined,
 37 |     },
 38 |     onlyRenderSelf: {
 39 |       type: Boolean,
 40 |       default: undefined,
 41 |     },
 42 |     mapProperties: {},
 43 |     filterProperties: {},
 44 |   },
 45 |   setup(props: IRecursionFieldProps) {
 46 |     const parentRef = useField()
 47 |     const optionsRef = inject(SchemaOptionsSymbol)
 48 |     const scopeRef = inject(SchemaExpressionScopeSymbol)
 49 |     const createSchema = (schemaProp: IRecursionFieldProps['schema']) =>
 50 |       markRaw(new Schema(schemaProp))
 51 |     const fieldSchemaRef = computed(() => createSchema(props.schema))
 52 | 
 53 |     const getPropsFromSchema = (schema: Schema) =>
 54 |       schema?.toFieldProps?.({
 55 |         ...optionsRef.value,
 56 |         get scope() {
 57 |           return lazyMerge(optionsRef.value.scope, scopeRef.value)
 58 |         },
 59 |       })
 60 |     const fieldPropsRef = shallowRef(getPropsFromSchema(fieldSchemaRef.value))
 61 | 
 62 |     watch([fieldSchemaRef, optionsRef], () => {
 63 |       fieldPropsRef.value = getPropsFromSchema(fieldSchemaRef.value)
 64 |     })
 65 | 
 66 |     const getBasePath = () => {
 67 |       if (props.onlyRenderProperties) {
 68 |         return props.basePath ?? parentRef?.value?.address.concat(props.name)
 69 |       }
 70 |       return props.basePath ?? parentRef?.value?.address
 71 |     }
 72 | 
 73 |     provide(SchemaSymbol, fieldSchemaRef)
 74 | 
 75 |     return () => {
 76 |       const basePath = getBasePath()
 77 |       const fieldProps = fieldPropsRef.value
 78 | 
 79 |       const generateSlotsByProperties = (scoped = false) => {
 80 |         if (props.onlyRenderSelf) return {}
 81 |         const properties = Schema.getOrderProperties(fieldSchemaRef.value)
 82 |         if (!properties.length) return {}
 83 |         const renderMap: Record<string, ((field?: GeneralField) => unknown)[]> =
 84 |           {}
 85 |         const setRender = (
 86 |           key: string,
 87 |           value: (field?: GeneralField) => unknown
 88 |         ) => {
 89 |           if (!renderMap[key]) {
 90 |             renderMap[key] = []
 91 |           }
 92 |           renderMap[key].push(value)
 93 |         }
 94 |         properties.forEach(({ schema: item, key: name }, index) => {
 95 |           let schema: Schema = item
 96 |           if (isFn(props.mapProperties)) {
 97 |             const mapped = props.mapProperties(item, name)
 98 |             if (mapped) {
 99 |               schema = mapped
100 |             }
101 |           }
102 |           if (isFn(props.filterProperties)) {
103 |             if (props.filterProperties(schema, name) === false) {
104 |               return null
105 |             }
106 |           }
107 |           setRender(schema['x-slot'] ?? 'default', (field?: GeneralField) =>
108 |             h(
109 |               RecursionField,
110 |               {
111 |                 key: `${index}-${name}`,
112 |                 attrs: {
113 |                   schema,
114 |                   name,
115 |                   basePath: field?.address ?? basePath,
116 |                 },
117 |                 slot: schema['x-slot'],
118 |               },
119 |               {}
120 |             )
121 |           )
122 |         })
123 |         const slots = {}
124 |         Object.keys(renderMap).forEach((key) => {
125 |           const renderFns = renderMap[key]
126 |           slots[key] = scoped
127 |             ? ({ field }) => renderFns.map((fn) => fn(field))
128 |             : () => renderFns.map((fn) => fn())
129 |         })
130 |         return slots
131 |       }
132 | 
133 |       const render = () => {
134 |         if (!isValid(props.name))
135 |           return resolveEmptySlot(generateSlotsByProperties())
136 |         if (fieldSchemaRef.value.type === 'object') {
137 |           if (props.onlyRenderProperties)
138 |             return resolveEmptySlot(generateSlotsByProperties())
139 |           return h(
140 |             ObjectField,
141 |             {
142 |               attrs: {
143 |                 ...fieldProps,
144 |                 name: props.name,
145 |                 basePath: basePath,
146 |               },
147 |             },
148 |             generateSlotsByProperties(true)
149 |           )
150 |         } else if (fieldSchemaRef.value.type === 'array') {
151 |           return h(
152 |             ArrayField,
153 |             {
154 |               attrs: {
155 |                 ...fieldProps,
156 |                 name: props.name,
157 |                 basePath: basePath,
158 |               },
159 |             },
160 |             {}
161 |           )
162 |         } else if (fieldSchemaRef.value.type === 'void') {
163 |           if (props.onlyRenderProperties)
164 |             return resolveEmptySlot(generateSlotsByProperties())
165 |           const slots = generateSlotsByProperties(true)
166 |           return h(
167 |             VoidField,
168 |             {
169 |               attrs: {
170 |                 ...fieldProps,
171 |                 name: props.name,
172 |                 basePath: basePath,
173 |               },
174 |             },
175 |             slots
176 |           )
177 |         }
178 | 
179 |         return h(
180 |           Field,
181 |           {
182 |             attrs: {
183 |               ...fieldProps,
184 |               name: props.name,
185 |               basePath: basePath,
186 |             },
187 |           },
188 |           {}
189 |         )
190 |       }
191 | 
192 |       if (!fieldSchemaRef.value) return
193 | 
194 |       return render()
195 |     }
196 |   },
197 | } as unknown as DefineComponent<IRecursionFieldProps>
198 | 
199 | export default RecursionField
200 | 
```

--------------------------------------------------------------------------------
/packages/next/docs/components/FormTab.md:
--------------------------------------------------------------------------------

```markdown
  1 | # FormTab
  2 | 
  3 | > Tab form
  4 | >
  5 | > Note: This component is only applicable to Schema scenarios
  6 | 
  7 | ## Markup Schema example
  8 | 
  9 | ```tsx
 10 | import React from 'react'
 11 | import {
 12 |   FormTab,
 13 |   FormItem,
 14 |   Input,
 15 |   FormButtonGroup,
 16 |   Submit,
 17 | } from '@formily/next'
 18 | import { createForm } from '@formily/core'
 19 | import { FormProvider, createSchemaField } from '@formily/react'
 20 | import { Button } from '@alifd/next'
 21 | 
 22 | const SchemaField = createSchemaField({
 23 |   components: {
 24 |     FormItem,
 25 |     FormTab,
 26 |     Input,
 27 |   },
 28 | })
 29 | 
 30 | const form = createForm()
 31 | const formTab = FormTab.createFormTab()
 32 | 
 33 | export default () => {
 34 |   return (
 35 |     <FormProvider form={form}>
 36 |       <SchemaField>
 37 |         <SchemaField.Void
 38 |           type="void"
 39 |           x-component="FormTab"
 40 |           x-component-props={{ formTab }}
 41 |         >
 42 |           <SchemaField.Void
 43 |             type="void"
 44 |             name="tab1"
 45 |             x-component="FormTab.TabPane"
 46 |             x-component-props={{ tab: 'A1' }}
 47 |           >
 48 |             <SchemaField.String
 49 |               name="aaa"
 50 |               x-decorator="FormItem"
 51 |               title="AAA"
 52 |               required
 53 |               x-component="Input"
 54 |             />
 55 |           </SchemaField.Void>
 56 |           <SchemaField.Void
 57 |             name="tab2"
 58 |             x-component="FormTab.TabPane"
 59 |             x-component-props={{ tab: 'A2' }}
 60 |           >
 61 |             <SchemaField.String
 62 |               name="bbb"
 63 |               x-decorator="FormItem"
 64 |               title="BBB"
 65 |               required
 66 |               x-component="Input"
 67 |             />
 68 |           </SchemaField.Void>
 69 |           <SchemaField.Void
 70 |             name="tab3"
 71 |             x-component="FormTab.TabPane"
 72 |             x-component-props={{ tab: 'A3' }}
 73 |           >
 74 |             <SchemaField.String
 75 |               name="ccc"
 76 |               x-decorator="FormItem"
 77 |               title="CCC"
 78 |               required
 79 |               x-component="Input"
 80 |             />
 81 |           </SchemaField.Void>
 82 |         </SchemaField.Void>
 83 |       </SchemaField>
 84 |       <FormButtonGroup.FormItem>
 85 |         <Button
 86 |           onClick={() => {
 87 |             form.query('tab3').take((field) => {
 88 |               field.visible = !field.visible
 89 |             })
 90 |           }}
 91 |         >
 92 |           Show/hide the last tab
 93 |         </Button>
 94 |         <Button
 95 |           onClick={() => {
 96 |             formTab.setActiveKey('tab2')
 97 |           }}
 98 |         >
 99 |           Switch to the second Tab
100 |         </Button>
101 |         <Submit onSubmit={console.log}>Submit</Submit>
102 |       </FormButtonGroup.FormItem>
103 |     </FormProvider>
104 |   )
105 | }
106 | ```
107 | 
108 | ## JSON Schema case
109 | 
110 | ```tsx
111 | import React from 'react'
112 | import {
113 |   FormTab,
114 |   FormItem,
115 |   Input,
116 |   FormButtonGroup,
117 |   Submit,
118 | } from '@formily/next'
119 | import { createForm } from '@formily/core'
120 | import { FormProvider, createSchemaField } from '@formily/react'
121 | import { Button } from '@alifd/next'
122 | 
123 | const SchemaField = createSchemaField({
124 |   components: {
125 |     FormItem,
126 |     FormTab,
127 |     Input,
128 |   },
129 | })
130 | 
131 | const form = createForm()
132 | const formTab = FormTab.createFormTab()
133 | 
134 | const schema = {
135 |   type: 'object',
136 |   properties: {
137 |     collapse: {
138 |       type: 'void',
139 |       'x-component': 'FormTab',
140 |       'x-component-props': {
141 |         formTab: '{{formTab}}',
142 |       },
143 |       properties: {
144 |         tab1: {
145 |           type: 'void',
146 |           'x-component': 'FormTab.TabPane',
147 |           'x-component-props': {
148 |             tab: 'A1',
149 |           },
150 |           properties: {
151 |             aaa: {
152 |               type: 'string',
153 |               title: 'AAA',
154 |               'x-decorator': 'FormItem',
155 |               required: true,
156 |               'x-component': 'Input',
157 |             },
158 |           },
159 |         },
160 |         tab2: {
161 |           type: 'void',
162 |           'x-component': 'FormTab.TabPane',
163 |           'x-component-props': {
164 |             tab: 'A2',
165 |           },
166 |           properties: {
167 |             bbb: {
168 |               type: 'string',
169 |               title: 'BBB',
170 |               'x-decorator': 'FormItem',
171 |               required: true,
172 |               'x-component': 'Input',
173 |             },
174 |           },
175 |         },
176 |         tab3: {
177 |           type: 'void',
178 |           'x-component': 'FormTab.TabPane',
179 |           'x-component-props': {
180 |             tab: 'A3',
181 |           },
182 |           properties: {
183 |             ccc: {
184 |               type: 'string',
185 |               title: 'CCC',
186 |               'x-decorator': 'FormItem',
187 |               required: true,
188 |               'x-component': 'Input',
189 |             },
190 |           },
191 |         },
192 |       },
193 |     },
194 |   },
195 | }
196 | 
197 | export default () => {
198 |   return (
199 |     <FormProvider form={form}>
200 |       <SchemaField schema={schema} scope={{ formTab }} />
201 |       <FormButtonGroup.FormItem>
202 |         <Button
203 |           onClick={() => {
204 |             form.query('tab3').take((field) => {
205 |               field.visible = !field.visible
206 |             })
207 |           }}
208 |         >
209 |           Show/hide the last tab
210 |         </Button>
211 |         <Button
212 |           onClick={() => {
213 |             formTab.setActiveKey('tab2')
214 |           }}
215 |         >
216 |           Switch to the second Tab
217 |         </Button>
218 |         <Submit onSubmit={console.log}>Submit</Submit>
219 |       </FormButtonGroup.FormItem>
220 |     </FormProvider>
221 |   )
222 | }
223 | ```
224 | 
225 | ## API
226 | 
227 | ### FormTab
228 | 
229 | | Property name | Type     | Description                                           | Default value |
230 | | ------------- | -------- | ----------------------------------------------------- | ------------- |
231 | | formTab       | IFormTab | Pass in the model created by createFormTab/useFormTab |               |
232 | 
233 | Other references https://fusion.design/pc/component/basic/tab
234 | 
235 | ### FormTab.TabPane
236 | 
237 | Refer to the Item property of https://fusion.design/pc/component/basic/tab
238 | 
239 | ### FormTab.createFormTab
240 | 
241 | ```ts pure
242 | type ActiveKey = string | number
243 | 
244 | interface createFormTab {
245 |   (defaultActiveKey?: ActiveKey): IFormTab
246 | }
247 | 
248 | interface IFormTab {
249 |   //Activate the primary key
250 |   activeKey: ActiveKey
251 |   //Set the activation key
252 |   setActiveKey(key: ActiveKey): void
253 | }
254 | ```
255 | 
```
Page 17/52FirstPrevNextLast