#
tokens: 49384/50000 28/1152 files (page 10/52)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 10 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/form-layout/useResponsiveFormLayout.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { useRef, useState, useEffect } from 'react'
  2 | import { isArr, isValid } from '@formily/shared'
  3 | 
  4 | interface IProps {
  5 |   breakpoints?: number[]
  6 |   layout?:
  7 |     | 'vertical'
  8 |     | 'horizontal'
  9 |     | 'inline'
 10 |     | ('vertical' | 'horizontal' | 'inline')[]
 11 |   labelCol?: number | number[]
 12 |   wrapperCol?: number | number[]
 13 |   labelAlign?: 'right' | 'left' | ('right' | 'left')[]
 14 |   wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]
 15 |   [props: string]: any
 16 | }
 17 | 
 18 | interface ICalcBreakpointIndex {
 19 |   (originalBreakpoints: number[], width: number): number
 20 | }
 21 | 
 22 | interface ICalculateProps {
 23 |   (target: HTMLElement, props: IProps): IProps
 24 | }
 25 | 
 26 | interface IUseResponsiveFormLayout {
 27 |   (props: IProps): {
 28 |     ref: React.MutableRefObject<HTMLDivElement>
 29 |     props: any
 30 |   }
 31 | }
 32 | 
 33 | const calcBreakpointIndex: ICalcBreakpointIndex = (breakpoints, width) => {
 34 |   for (let i = 0; i < breakpoints.length; i++) {
 35 |     if (width <= breakpoints[i]) {
 36 |       return i
 37 |     }
 38 |   }
 39 | }
 40 | 
 41 | const calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {
 42 |   if (Array.isArray(value)) {
 43 |     if (breakpointIndex === -1) return value[0]
 44 |     return value[breakpointIndex] ?? value[value.length - 1]
 45 |   } else {
 46 |     return value
 47 |   }
 48 | }
 49 | 
 50 | const factor = <T>(value: T | T[], breakpointIndex: number): T =>
 51 |   isValid(value) ? calcFactor(value as any, breakpointIndex) : value
 52 | 
 53 | const calculateProps: ICalculateProps = (target, props) => {
 54 |   const { clientWidth } = target
 55 |   const {
 56 |     breakpoints,
 57 |     layout,
 58 |     labelAlign,
 59 |     wrapperAlign,
 60 |     labelCol,
 61 |     wrapperCol,
 62 |     ...otherProps
 63 |   } = props
 64 |   const breakpointIndex = calcBreakpointIndex(breakpoints, clientWidth)
 65 | 
 66 |   return {
 67 |     layout: factor(layout, breakpointIndex),
 68 |     labelAlign: factor(labelAlign, breakpointIndex),
 69 |     wrapperAlign: factor(wrapperAlign, breakpointIndex),
 70 |     labelCol: factor(labelCol, breakpointIndex),
 71 |     wrapperCol: factor(wrapperCol, breakpointIndex),
 72 |     ...otherProps,
 73 |   }
 74 | }
 75 | 
 76 | export const useResponsiveFormLayout: IUseResponsiveFormLayout = (props) => {
 77 |   const ref = useRef<HTMLDivElement>(null)
 78 |   const { breakpoints } = props
 79 |   if (!isArr(breakpoints)) {
 80 |     return { ref, props }
 81 |   }
 82 |   const [layoutProps, setLayout] = useState<any>(props)
 83 | 
 84 |   const updateUI = () => {
 85 |     if (ref.current) {
 86 |       setLayout(calculateProps(ref.current, props))
 87 |     }
 88 |   }
 89 | 
 90 |   useEffect(() => {
 91 |     const observer = () => {
 92 |       updateUI()
 93 |     }
 94 |     const resizeObserver = new ResizeObserver(observer)
 95 |     if (ref.current) {
 96 |       resizeObserver.observe(ref.current)
 97 |     }
 98 |     updateUI()
 99 |     return () => {
100 |       resizeObserver.disconnect()
101 |     }
102 |   }, [])
103 | 
104 |   return {
105 |     ref,
106 |     props: layoutProps,
107 |   }
108 | }
109 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/form-collapse/markup-schema.vue:
--------------------------------------------------------------------------------

```vue
  1 | <template>
  2 |   <Form :form="form" :label-col="6" :wrapper-col="10">
  3 |     <SchemaField>
  4 |       <SchemaVoidField
  5 |         type="void"
  6 |         title="折叠面板"
  7 |         x-decorator="FormItem"
  8 |         x-component="FormCollapse"
  9 |         :x-component-props="{ formCollapse }"
 10 |       >
 11 |         <SchemaVoidField
 12 |           type="void"
 13 |           name="tab1"
 14 |           x-component="FormCollapse.Item"
 15 |           :x-component-props="{ title: 'A1' }"
 16 |         >
 17 |           <SchemaStringField
 18 |             name="aaa"
 19 |             x-decorator="FormItem"
 20 |             title="AAA"
 21 |             required
 22 |             x-component="Input"
 23 |           />
 24 |         </SchemaVoidField>
 25 |         <SchemaVoidField
 26 |           name="tab2"
 27 |           x-component="FormCollapse.Item"
 28 |           :x-component-props="{ title: 'A2' }"
 29 |         >
 30 |           <SchemaStringField
 31 |             name="bbb"
 32 |             x-decorator="FormItem"
 33 |             title="BBB"
 34 |             required
 35 |             x-component="Input"
 36 |           />
 37 |         </SchemaVoidField>
 38 |         <SchemaVoidField
 39 |           name="tab3"
 40 |           x-component="FormCollapse.Item"
 41 |           :x-component-props="{ title: 'A3' }"
 42 |         >
 43 |           <SchemaStringField
 44 |             name="ccc"
 45 |             x-decorator="FormItem"
 46 |             title="CCC"
 47 |             required
 48 |             x-component="Input"
 49 |           />
 50 |         </SchemaVoidField>
 51 |       </SchemaVoidField>
 52 |     </SchemaField>
 53 |     <FormButtonGroup alignFormItem>
 54 |       <Button
 55 |         @click="
 56 |           () => {
 57 |             form.query('tab3').take((field) => {
 58 |               field.visible = !field.visible
 59 |             })
 60 |           }
 61 |         "
 62 |       >
 63 |         显示/隐藏最后一个Tab
 64 |       </Button>
 65 |       <Button
 66 |         @click="
 67 |           () => {
 68 |             formCollapse.toggleActiveKey('tab2')
 69 |           }
 70 |         "
 71 |       >
 72 |         切换第二个Tab
 73 |       </Button>
 74 |       <Submit @submit="log">提交</Submit>
 75 |     </FormButtonGroup>
 76 |   </Form>
 77 | </template>
 78 | 
 79 | <script>
 80 | import { createForm } from '@formily/core'
 81 | import { createSchemaField } from '@formily/vue'
 82 | import {
 83 |   FormItem,
 84 |   FormCollapse,
 85 |   FormButtonGroup,
 86 |   Submit,
 87 |   Input,
 88 |   Form,
 89 | } from '@formily/element'
 90 | import { Button } from 'element-ui'
 91 | 
 92 | const SchemaField = createSchemaField({
 93 |   components: {
 94 |     FormItem,
 95 |     FormCollapse,
 96 |     Input,
 97 |   },
 98 | })
 99 | 
100 | export default {
101 |   components: {
102 |     Form,
103 |     FormButtonGroup,
104 |     Button,
105 |     Submit,
106 |     ...SchemaField,
107 |   },
108 | 
109 |   data() {
110 |     const form = createForm()
111 |     const formCollapse = FormCollapse.createFormCollapse()
112 | 
113 |     return {
114 |       form,
115 |       formCollapse,
116 |     }
117 |   },
118 |   methods: {
119 |     log(values) {
120 |       console.log(values)
121 |     },
122 |   },
123 | }
124 | </script>
125 | 
126 | <style lang="scss" scoped></style>
127 | 
```

--------------------------------------------------------------------------------
/packages/next/src/form-layout/useResponsiveFormLayout.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { useRef, useState, useEffect } from 'react'
  2 | import { isArr, isValid } from '@formily/shared'
  3 | 
  4 | interface IProps {
  5 |   breakpoints?: number[]
  6 |   layout?:
  7 |     | 'vertical'
  8 |     | 'horizontal'
  9 |     | 'inline'
 10 |     | ('vertical' | 'horizontal' | 'inline')[]
 11 |   labelCol?: number | number[]
 12 |   wrapperCol?: number | number[]
 13 |   labelAlign?: 'right' | 'left' | ('right' | 'left')[]
 14 |   wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]
 15 |   [props: string]: any
 16 | }
 17 | 
 18 | interface ICalcBreakpointIndex {
 19 |   (originalBreakpoints: number[], width: number): number
 20 | }
 21 | 
 22 | interface ICalculateProps {
 23 |   (target: HTMLElement, props: IProps): IProps
 24 | }
 25 | 
 26 | interface IUseResponsiveFormLayout {
 27 |   (props: IProps): {
 28 |     ref: React.MutableRefObject<HTMLDivElement>
 29 |     props: any
 30 |   }
 31 | }
 32 | 
 33 | const calcBreakpointIndex: ICalcBreakpointIndex = (breakpoints, width) => {
 34 |   for (let i = 0; i < breakpoints.length; i++) {
 35 |     if (width <= breakpoints[i]) {
 36 |       return i
 37 |     }
 38 |   }
 39 | }
 40 | 
 41 | const calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {
 42 |   if (Array.isArray(value)) {
 43 |     if (breakpointIndex === -1) return value[0]
 44 |     return value[breakpointIndex] ?? value[value.length - 1]
 45 |   } else {
 46 |     return value
 47 |   }
 48 | }
 49 | 
 50 | const factor = <T>(value: T | T[], breakpointIndex: number): T =>
 51 |   isValid(value) ? calcFactor(value as any, breakpointIndex) : value
 52 | 
 53 | const calculateProps: ICalculateProps = (target, props) => {
 54 |   const { clientWidth } = target
 55 |   const {
 56 |     breakpoints,
 57 |     layout,
 58 |     labelAlign,
 59 |     wrapperAlign,
 60 |     labelCol,
 61 |     wrapperCol,
 62 |     ...otherProps
 63 |   } = props
 64 |   const breakpointIndex = calcBreakpointIndex(breakpoints, clientWidth)
 65 | 
 66 |   return {
 67 |     layout: factor(layout, breakpointIndex),
 68 |     labelAlign: factor(labelAlign, breakpointIndex),
 69 |     wrapperAlign: factor(wrapperAlign, breakpointIndex),
 70 |     labelCol: factor(labelCol, breakpointIndex),
 71 |     wrapperCol: factor(wrapperCol, breakpointIndex),
 72 |     ...otherProps,
 73 |   }
 74 | }
 75 | 
 76 | export const useResponsiveFormLayout: IUseResponsiveFormLayout = (props) => {
 77 |   const ref = useRef<HTMLDivElement>(null)
 78 |   const { breakpoints } = props
 79 |   if (!isArr(breakpoints)) {
 80 |     return { ref, props }
 81 |   }
 82 |   const [layoutProps, setLayout] = useState<IProps>(props)
 83 | 
 84 |   const updateUI = () => {
 85 |     if (ref.current) {
 86 |       setLayout(calculateProps(ref.current, props))
 87 |     }
 88 |   }
 89 | 
 90 |   useEffect(() => {
 91 |     const observer = () => {
 92 |       updateUI()
 93 |     }
 94 |     const resizeObserver = new ResizeObserver(observer)
 95 |     if (ref.current) {
 96 |       resizeObserver.observe(ref.current)
 97 |     }
 98 |     updateUI()
 99 |     return () => {
100 |       resizeObserver.disconnect()
101 |     }
102 |   }, [])
103 | 
104 |   return {
105 |     ref,
106 |     props: layoutProps,
107 |   }
108 | }
109 | 
```

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

```markdown
  1 | # Radio
  2 | 
  3 | > Single selection box
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 10 | import { createForm } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | 
 13 | const SchemaField = createSchemaField({
 14 |   components: {
 15 |     Radio,
 16 |     FormItem,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => (
 23 |   <FormProvider form={form}>
 24 |     <SchemaField>
 25 |       <SchemaField.Number
 26 |         name="radio"
 27 |         title="single choice"
 28 |         enum={[
 29 |           {
 30 |             label: 'Option 1',
 31 |             value: 1,
 32 |           },
 33 |           {
 34 |             label: 'Option 2',
 35 |             value: 2,
 36 |           },
 37 |         ]}
 38 |         x-decorator="FormItem"
 39 |         x-component="Radio.Group"
 40 |       />
 41 |     </SchemaField>
 42 |     <FormButtonGroup>
 43 |       <Submit onSubmit={console.log}>Submit</Submit>
 44 |     </FormButtonGroup>
 45 |   </FormProvider>
 46 | )
 47 | ```
 48 | 
 49 | ## JSON Schema case
 50 | 
 51 | ```tsx
 52 | import React from 'react'
 53 | import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 54 | import { createForm } from '@formily/core'
 55 | import { FormProvider, createSchemaField } from '@formily/react'
 56 | 
 57 | const SchemaField = createSchemaField({
 58 |   components: {
 59 |     Radio,
 60 |     FormItem,
 61 |   },
 62 | })
 63 | 
 64 | const form = createForm()
 65 | 
 66 | const schema = {
 67 |   type: 'object',
 68 |   properties: {
 69 |     radio: {
 70 |       type: 'number',
 71 |       title: 'Single selection',
 72 |       enum: [
 73 |         {
 74 |           label: 'Option 1',
 75 |           value: 1,
 76 |         },
 77 |         {
 78 |           label: 'Option 2',
 79 |           value: 2,
 80 |         },
 81 |       ],
 82 |       'x-decorator': 'FormItem',
 83 |       'x-component': 'Radio.Group',
 84 |     },
 85 |   },
 86 | }
 87 | 
 88 | export default () => (
 89 |   <FormProvider form={form}>
 90 |     <SchemaField schema={schema} />
 91 |     <FormButtonGroup>
 92 |       <Submit onSubmit={console.log}>Submit</Submit>
 93 |     </FormButtonGroup>
 94 |   </FormProvider>
 95 | )
 96 | ```
 97 | 
 98 | ## Pure JSX case
 99 | 
100 | ```tsx
101 | import React from 'react'
102 | import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'
103 | import { createForm } from '@formily/core'
104 | import { FormProvider, Field } from '@formily/react'
105 | 
106 | const form = createForm()
107 | 
108 | export default () => (
109 |   <FormProvider form={form}>
110 |     <Field
111 |       name="radio"
112 |       title="single choice"
113 |       dataSource={[
114 |         {
115 |           label: 'Option 1',
116 |           value: 1,
117 |         },
118 |         {
119 |           label: 'Option 2',
120 |           value: 2,
121 |         },
122 |       ]}
123 |       decorator={FormItem}
124 |       component={Radio.Group}
125 |     />
126 |     <FormButtonGroup>
127 |       <Submit onSubmit={console.log}>Submit</Submit>
128 |     </FormButtonGroup>
129 |   </FormProvider>
130 | )
131 | ```
132 | 
133 | ## API
134 | 
135 | Reference https://ant.design/components/radio-cn/
136 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/array-cards/effects-markup-schema.vue:
--------------------------------------------------------------------------------

```vue
  1 | <template>
  2 |   <FormProvider :form="form">
  3 |     <SchemaField>
  4 |       <SchemaArrayField
  5 |         name="array"
  6 |         :maxItems="3"
  7 |         x-component="ArrayCards"
  8 |         x-decorator="FormItem"
  9 |         :x-component-props="{
 10 |           title: '对象数组',
 11 |         }"
 12 |       >
 13 |         <SchemaObjectField>
 14 |           <SchemaVoidField x-component="ArrayCards.Index" />
 15 |           <SchemaStringField
 16 |             name="aa"
 17 |             x-decorator="FormItem"
 18 |             title="AA"
 19 |             required
 20 |             description="AA输入123时隐藏BB"
 21 |             x-component="Input"
 22 |           />
 23 |           <SchemaStringField
 24 |             name="bb"
 25 |             x-decorator="FormItem"
 26 |             title="BB"
 27 |             required
 28 |             x-component="Input"
 29 |           />
 30 |           <SchemaStringField
 31 |             name="cc"
 32 |             x-decorator="FormItem"
 33 |             title="CC"
 34 |             required
 35 |             description="CC输入123时隐藏DD"
 36 |             x-component="Input"
 37 |           />
 38 |           <SchemaStringField
 39 |             name="dd"
 40 |             x-decorator="FormItem"
 41 |             title="DD"
 42 |             required
 43 |             x-component="Input"
 44 |           />
 45 |           <SchemaVoidField x-component="ArrayCards.Remove" />
 46 |           <SchemaVoidField x-component="ArrayCards.MoveUp" />
 47 |           <SchemaVoidField x-component="ArrayCards.MoveDown" />
 48 |         </SchemaObjectField>
 49 |         <SchemaVoidField x-component="ArrayCards.Addition" title="添加条目" />
 50 |       </SchemaArrayField>
 51 |     </SchemaField>
 52 |     <Submit @submit="log">提交</Submit>
 53 |   </FormProvider>
 54 | </template>
 55 | 
 56 | <script>
 57 | import { createForm, onFieldChange, onFieldReact } from '@formily/core'
 58 | import { FormProvider, createSchemaField } from '@formily/vue'
 59 | import {
 60 |   FormItem,
 61 |   FormButtonGroup,
 62 |   Submit,
 63 |   Input,
 64 |   ArrayCards,
 65 | } from '@formily/element'
 66 | import { Button } from 'element-ui'
 67 | 
 68 | const SchemaField = createSchemaField({
 69 |   components: {
 70 |     FormItem,
 71 |     Input,
 72 |     ArrayCards,
 73 |   },
 74 | })
 75 | 
 76 | export default {
 77 |   components: {
 78 |     FormProvider,
 79 |     FormButtonGroup,
 80 |     Button,
 81 |     Submit,
 82 |     ...SchemaField,
 83 |   },
 84 | 
 85 |   data() {
 86 |     const form = createForm({
 87 |       effects: () => {
 88 |         //主动联动模式
 89 |         onFieldChange('array.*.aa', ['value'], (field, form) => {
 90 |           form.setFieldState(field.query('.bb'), (state) => {
 91 |             state.visible = field.value != '123'
 92 |           })
 93 |         })
 94 |         //被动联动模式
 95 |         onFieldReact('array.*.dd', (field) => {
 96 |           field.visible = field.query('.cc').get('value') != '123'
 97 |         })
 98 |       },
 99 |     })
100 | 
101 |     return {
102 |       form,
103 |     }
104 |   },
105 |   methods: {
106 |     log(values) {
107 |       console.log(values)
108 |     },
109 |   },
110 | }
111 | </script>
112 | 
113 | <style lang="scss" scoped></style>
114 | 
```

--------------------------------------------------------------------------------
/packages/vue/docs/.vuepress/components/createCodeSandBox.js:
--------------------------------------------------------------------------------

```javascript
  1 | import { getParameters } from 'codesandbox/lib/api/define'
  2 | 
  3 | const CodeSandBoxHTML = '<div id="app"></div>'
  4 | const CodeSandBoxJS = `
  5 | import Vue from 'vue'
  6 | import Antd from 'ant-design-vue';
  7 | import 'ant-design-vue/dist/antd.css';
  8 | import App from './App.vue'
  9 | 
 10 | Vue.config.productionTip = false;
 11 | 
 12 | Vue.use(Antd);
 13 | 
 14 | 
 15 | new Vue({
 16 |   render: h => h(App),
 17 | }).$mount('#app')`
 18 | 
 19 | const createForm = ({ method, action, data }) => {
 20 |   const form = document.createElement('form') // 构造 form
 21 |   form.style.display = 'none' // 设置为不显示
 22 |   form.target = '_blank' // 指向 iframe
 23 | 
 24 |   // 构造 formdata
 25 |   Object.keys(data).forEach((key) => {
 26 |     const input = document.createElement('input') // 创建 input
 27 | 
 28 |     input.name = key // 设置 name
 29 |     input.value = data[key] // 设置 value
 30 | 
 31 |     form.appendChild(input)
 32 |   })
 33 | 
 34 |   form.method = method // 设置方法
 35 |   form.action = action // 设置地址
 36 | 
 37 |   document.body.appendChild(form)
 38 | 
 39 |   // 对该 form 执行提交
 40 |   form.submit()
 41 | 
 42 |   document.body.removeChild(form)
 43 | }
 44 | 
 45 | export function createCodeSandBox(codeStr) {
 46 |   const parameters = getParameters({
 47 |     files: {
 48 |       'sandbox.config.json': {
 49 |         content: {
 50 |           template: 'node',
 51 |           infiniteLoopProtection: true,
 52 |           hardReloadOnChange: false,
 53 |           view: 'browser',
 54 |           container: {
 55 |             port: 8080,
 56 |             node: '14',
 57 |           },
 58 |         },
 59 |       },
 60 |       'package.json': {
 61 |         content: {
 62 |           scripts: {
 63 |             serve: 'vue-cli-service serve',
 64 |             build: 'vue-cli-service build',
 65 |             lint: 'vue-cli-service lint',
 66 |           },
 67 |           dependencies: {
 68 |             '@formily/core': 'latest',
 69 |             '@formily/vue': 'latest',
 70 |             'core-js': '^3.6.5',
 71 |             'ant-design-vue': 'latest',
 72 |             'vue-demi': 'latest',
 73 |             vue: '^2.6.11',
 74 |           },
 75 |           devDependencies: {
 76 |             '@vue/cli-plugin-babel': '~4.5.0',
 77 |             '@vue/cli-service': '~4.5.0',
 78 |             '@vue/composition-api': 'latest',
 79 |             'vue-template-compiler': '^2.6.11',
 80 |           },
 81 |           babel: {
 82 |             presets: ['@vue/cli-plugin-babel/preset'],
 83 |           },
 84 |           vue: {
 85 |             devServer: {
 86 |               host: '0.0.0.0',
 87 |               disableHostCheck: true, // 必须
 88 |             },
 89 |           },
 90 |         },
 91 |       },
 92 |       'src/App.vue': {
 93 |         content: codeStr,
 94 |       },
 95 |       'src/main.js': {
 96 |         content: CodeSandBoxJS,
 97 |       },
 98 |       'public/index.html': {
 99 |         content: CodeSandBoxHTML,
100 |       },
101 |     },
102 |   })
103 | 
104 |   createForm({
105 |     method: 'post',
106 |     action: 'https://codesandbox.io/api/v1/sandboxes/define',
107 |     data: {
108 |       parameters,
109 |       query: 'file=/src/App.vue',
110 |     },
111 |   })
112 | }
113 | 
```

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

```markdown
  1 | # Radio
  2 | 
  3 | > Single selection box
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Radio, 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 |     Radio,
 16 |     FormItem,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => (
 23 |   <FormProvider form={form}>
 24 |     <SchemaField>
 25 |       <SchemaField.Number
 26 |         name="radio"
 27 |         title="single choice"
 28 |         enum={[
 29 |           {
 30 |             label: 'Option 1',
 31 |             value: 1,
 32 |           },
 33 |           {
 34 |             label: 'Option 2',
 35 |             value: 2,
 36 |           },
 37 |         ]}
 38 |         x-decorator="FormItem"
 39 |         x-component="Radio.Group"
 40 |       />
 41 |     </SchemaField>
 42 |     <FormButtonGroup>
 43 |       <Submit onSubmit={console.log}>Submit</Submit>
 44 |     </FormButtonGroup>
 45 |   </FormProvider>
 46 | )
 47 | ```
 48 | 
 49 | ## JSON Schema case
 50 | 
 51 | ```tsx
 52 | import React from 'react'
 53 | import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'
 54 | import { createForm } from '@formily/core'
 55 | import { FormProvider, createSchemaField } from '@formily/react'
 56 | 
 57 | const SchemaField = createSchemaField({
 58 |   components: {
 59 |     Radio,
 60 |     FormItem,
 61 |   },
 62 | })
 63 | 
 64 | const form = createForm()
 65 | 
 66 | const schema = {
 67 |   type: 'object',
 68 |   properties: {
 69 |     radio: {
 70 |       type: 'number',
 71 |       title: 'Single selection',
 72 |       enum: [
 73 |         {
 74 |           label: 'Option 1',
 75 |           value: 1,
 76 |         },
 77 |         {
 78 |           label: 'Option 2',
 79 |           value: 2,
 80 |         },
 81 |       ],
 82 |       'x-decorator': 'FormItem',
 83 |       'x-component': 'Radio.Group',
 84 |     },
 85 |   },
 86 | }
 87 | 
 88 | export default () => (
 89 |   <FormProvider form={form}>
 90 |     <SchemaField schema={schema} />
 91 |     <FormButtonGroup>
 92 |       <Submit onSubmit={console.log}>Submit</Submit>
 93 |     </FormButtonGroup>
 94 |   </FormProvider>
 95 | )
 96 | ```
 97 | 
 98 | ## Pure JSX case
 99 | 
100 | ```tsx
101 | import React from 'react'
102 | import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'
103 | import { createForm } from '@formily/core'
104 | import { FormProvider, Field } from '@formily/react'
105 | 
106 | const form = createForm()
107 | 
108 | export default () => (
109 |   <FormProvider form={form}>
110 |     <Field
111 |       name="radio"
112 |       title="single choice"
113 |       dataSource={[
114 |         {
115 |           label: 'Option 1',
116 |           value: 1,
117 |         },
118 |         {
119 |           label: 'Option 2',
120 |           value: 2,
121 |         },
122 |       ]}
123 |       decorator={FormItem}
124 |       component={Radio.Group}
125 |     />
126 |     <FormButtonGroup>
127 |       <Submit onSubmit={console.log}>Submit</Submit>
128 |     </FormButtonGroup>
129 |   </FormProvider>
130 | )
131 | ```
132 | 
133 | ## API
134 | 
135 | Reference https://fusion.design/pc/component/basic/radio
136 | 
```

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

```markdown
  1 | # Transfer
  2 | 
  3 | > 穿梭框
  4 | 
  5 | ## Markup Schema 案例
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 10 | import { createForm } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | 
 13 | const SchemaField = createSchemaField({
 14 |   components: {
 15 |     Transfer,
 16 |     FormItem,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => (
 23 |   <FormProvider form={form}>
 24 |     <SchemaField>
 25 |       <SchemaField.Array
 26 |         name="transfer"
 27 |         title="穿梭框"
 28 |         x-decorator="FormItem"
 29 |         x-component="Transfer"
 30 |         enum={[
 31 |           { title: '选项1', key: 1 },
 32 |           { title: '选项2', key: 2 },
 33 |         ]}
 34 |         x-component-props={{
 35 |           render: (item) => item.title,
 36 |         }}
 37 |       />
 38 |     </SchemaField>
 39 |     <FormButtonGroup>
 40 |       <Submit onSubmit={console.log}>提交</Submit>
 41 |     </FormButtonGroup>
 42 |   </FormProvider>
 43 | )
 44 | ```
 45 | 
 46 | ## JSON Schema 案例
 47 | 
 48 | ```tsx
 49 | import React from 'react'
 50 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 51 | import { createForm } from '@formily/core'
 52 | import { FormProvider, createSchemaField } from '@formily/react'
 53 | 
 54 | const SchemaField = createSchemaField({
 55 |   components: {
 56 |     Transfer,
 57 |     FormItem,
 58 |   },
 59 | })
 60 | 
 61 | const form = createForm()
 62 | 
 63 | const schema = {
 64 |   type: 'object',
 65 |   properties: {
 66 |     transfer: {
 67 |       type: 'array',
 68 |       title: '穿梭框',
 69 |       'x-decorator': 'FormItem',
 70 |       'x-component': 'Transfer',
 71 |       enum: [
 72 |         { title: '选项1', key: 1 },
 73 |         { title: '选项2', key: 2 },
 74 |       ],
 75 |       'x-component-props': {
 76 |         render: '{{renderTitle}}',
 77 |       },
 78 |     },
 79 |   },
 80 | }
 81 | 
 82 | const renderTitle = (item) => item.title
 83 | 
 84 | export default () => (
 85 |   <FormProvider form={form}>
 86 |     <SchemaField schema={schema} scope={{ renderTitle }} />
 87 |     <FormButtonGroup>
 88 |       <Submit onSubmit={console.log}>提交</Submit>
 89 |     </FormButtonGroup>
 90 |   </FormProvider>
 91 | )
 92 | ```
 93 | 
 94 | ## 纯 JSX 案例
 95 | 
 96 | ```tsx
 97 | import React from 'react'
 98 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 99 | import { createForm } from '@formily/core'
100 | import { FormProvider, Field } from '@formily/react'
101 | 
102 | const form = createForm()
103 | 
104 | export default () => (
105 |   <FormProvider form={form}>
106 |     <Field
107 |       name="transfer"
108 |       title="穿梭框"
109 |       dataSource={[
110 |         { title: '选项1', key: 1 },
111 |         { title: '选项2', key: 2 },
112 |       ]}
113 |       decorator={[FormItem]}
114 |       component={[
115 |         Transfer,
116 |         {
117 |           render: (item) => item.title,
118 |         },
119 |       ]}
120 |     />
121 |     <FormButtonGroup>
122 |       <Submit onSubmit={console.log}>提交</Submit>
123 |     </FormButtonGroup>
124 |   </FormProvider>
125 | )
126 | ```
127 | 
128 | ## API
129 | 
130 | 参考 https://ant.design/components/transfer-cn/
131 | 
```

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

```markdown
  1 | # Password
  2 | 
  3 | > 密码输入框
  4 | 
  5 | ## Markup Schema 案例
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import {
 10 |   Password,
 11 |   FormItem,
 12 |   FormLayout,
 13 |   FormButtonGroup,
 14 |   Submit,
 15 | } from '@formily/antd'
 16 | import { createForm } from '@formily/core'
 17 | import { FormProvider, createSchemaField } from '@formily/react'
 18 | 
 19 | const SchemaField = createSchemaField({
 20 |   components: {
 21 |     Password,
 22 |     FormItem,
 23 |   },
 24 | })
 25 | 
 26 | const form = createForm()
 27 | 
 28 | export default () => (
 29 |   <FormProvider form={form}>
 30 |     <FormLayout labelCol={6} wrapperCol={10}>
 31 |       <SchemaField>
 32 |         <SchemaField.String
 33 |           name="input"
 34 |           title="输入框"
 35 |           x-decorator="FormItem"
 36 |           x-component="Password"
 37 |           required
 38 |           x-component-props={{
 39 |             checkStrength: true,
 40 |           }}
 41 |         />
 42 |       </SchemaField>
 43 |       <FormButtonGroup.FormItem>
 44 |         <Submit onSubmit={console.log}>提交</Submit>
 45 |       </FormButtonGroup.FormItem>
 46 |     </FormLayout>
 47 |   </FormProvider>
 48 | )
 49 | ```
 50 | 
 51 | ## JSON Schema 案例
 52 | 
 53 | ```tsx
 54 | import React from 'react'
 55 | import {
 56 |   Password,
 57 |   FormItem,
 58 |   FormLayout,
 59 |   FormButtonGroup,
 60 |   Submit,
 61 | } from '@formily/antd'
 62 | import { createForm } from '@formily/core'
 63 | import { FormProvider, createSchemaField } from '@formily/react'
 64 | 
 65 | const SchemaField = createSchemaField({
 66 |   components: {
 67 |     Password,
 68 |     FormItem,
 69 |   },
 70 | })
 71 | 
 72 | const form = createForm()
 73 | 
 74 | const schema = {
 75 |   type: 'object',
 76 |   properties: {
 77 |     input: {
 78 |       type: 'string',
 79 |       title: '输入框',
 80 |       'x-decorator': 'FormItem',
 81 |       'x-component': 'Password',
 82 |       'x-component-props': {
 83 |         checkStrength: true,
 84 |       },
 85 |     },
 86 |   },
 87 | }
 88 | 
 89 | export default () => (
 90 |   <FormProvider form={form}>
 91 |     <FormLayout labelCol={6} wrapperCol={10}>
 92 |       <SchemaField schema={schema} />
 93 |       <FormButtonGroup.FormItem>
 94 |         <Submit onSubmit={console.log}>提交</Submit>
 95 |       </FormButtonGroup.FormItem>
 96 |     </FormLayout>
 97 |   </FormProvider>
 98 | )
 99 | ```
100 | 
101 | ## 纯 JSX 案例
102 | 
103 | ```tsx
104 | import React from 'react'
105 | import {
106 |   Password,
107 |   FormItem,
108 |   FormLayout,
109 |   FormButtonGroup,
110 |   Submit,
111 | } from '@formily/antd'
112 | import { createForm } from '@formily/core'
113 | import { FormProvider, Field } from '@formily/react'
114 | const form = createForm()
115 | 
116 | export default () => (
117 |   <FormProvider form={form}>
118 |     <FormLayout labelCol={6} wrapperCol={10}>
119 |       <Field
120 |         name="input"
121 |         title="输入框"
122 |         required
123 |         decorator={[FormItem]}
124 |         component={[
125 |           Password,
126 |           {
127 |             checkStrength: true,
128 |           },
129 |         ]}
130 |       />
131 |       <FormButtonGroup.FormItem>
132 |         <Submit onSubmit={console.log}>提交</Submit>
133 |       </FormButtonGroup.FormItem>
134 |     </FormLayout>
135 |   </FormProvider>
136 | )
137 | ```
138 | 
139 | ## API
140 | 
141 | 参考 https://ant.design/components/input-cn/
142 | 
```

--------------------------------------------------------------------------------
/packages/core/src/effects/onFormEffects.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { isFn } from '@formily/shared'
 2 | import { autorun, batch } from '@formily/reactive'
 3 | import { Form } from '../models'
 4 | import { LifeCycleTypes } from '../types'
 5 | import { createEffectHook } from '../shared/effective'
 6 | 
 7 | function createFormEffect(type: LifeCycleTypes) {
 8 |   return createEffectHook(
 9 |     type,
10 |     (form: Form) => (callback: (form: Form) => void) => {
11 |       batch(() => {
12 |         callback(form)
13 |       })
14 |     }
15 |   )
16 | }
17 | 
18 | export const onFormInit = createFormEffect(LifeCycleTypes.ON_FORM_INIT)
19 | export const onFormMount = createFormEffect(LifeCycleTypes.ON_FORM_MOUNT)
20 | export const onFormUnmount = createFormEffect(LifeCycleTypes.ON_FORM_UNMOUNT)
21 | export const onFormValuesChange = createFormEffect(
22 |   LifeCycleTypes.ON_FORM_VALUES_CHANGE
23 | )
24 | export const onFormInitialValuesChange = createFormEffect(
25 |   LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE
26 | )
27 | export const onFormInputChange = createFormEffect(
28 |   LifeCycleTypes.ON_FORM_INPUT_CHANGE
29 | )
30 | export const onFormSubmit = createFormEffect(LifeCycleTypes.ON_FORM_SUBMIT)
31 | export const onFormReset = createFormEffect(LifeCycleTypes.ON_FORM_RESET)
32 | export const onFormSubmitStart = createFormEffect(
33 |   LifeCycleTypes.ON_FORM_SUBMIT_START
34 | )
35 | export const onFormSubmitEnd = createFormEffect(
36 |   LifeCycleTypes.ON_FORM_SUBMIT_END
37 | )
38 | export const onFormSubmitSuccess = createFormEffect(
39 |   LifeCycleTypes.ON_FORM_SUBMIT_SUCCESS
40 | )
41 | export const onFormSubmitFailed = createFormEffect(
42 |   LifeCycleTypes.ON_FORM_SUBMIT_FAILED
43 | )
44 | export const onFormSubmitValidateStart = createFormEffect(
45 |   LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_START
46 | )
47 | export const onFormSubmitValidateSuccess = createFormEffect(
48 |   LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_SUCCESS
49 | )
50 | export const onFormSubmitValidateFailed = createFormEffect(
51 |   LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_FAILED
52 | )
53 | export const onFormSubmitValidateEnd = createFormEffect(
54 |   LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_END
55 | )
56 | export const onFormValidateStart = createFormEffect(
57 |   LifeCycleTypes.ON_FORM_VALIDATE_START
58 | )
59 | export const onFormValidateSuccess = createFormEffect(
60 |   LifeCycleTypes.ON_FORM_VALIDATE_SUCCESS
61 | )
62 | export const onFormValidateFailed = createFormEffect(
63 |   LifeCycleTypes.ON_FORM_VALIDATE_FAILED
64 | )
65 | export const onFormValidateEnd = createFormEffect(
66 |   LifeCycleTypes.ON_FORM_VALIDATE_END
67 | )
68 | export const onFormGraphChange = createFormEffect(
69 |   LifeCycleTypes.ON_FORM_GRAPH_CHANGE
70 | )
71 | export const onFormLoading = createFormEffect(LifeCycleTypes.ON_FORM_LOADING)
72 | export function onFormReact(callback?: (form: Form) => void) {
73 |   let dispose = null
74 |   onFormInit((form) => {
75 |     dispose = autorun(() => {
76 |       if (isFn(callback)) callback(form)
77 |     })
78 |   })
79 |   onFormUnmount(() => {
80 |     dispose()
81 |   })
82 | }
83 | 
```

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

```markdown
  1 | # Password
  2 | 
  3 | > 密码输入框
  4 | 
  5 | ## Markup Schema 案例
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import {
 10 |   Password,
 11 |   FormItem,
 12 |   FormButtonGroup,
 13 |   Submit,
 14 |   FormLayout,
 15 | } from '@formily/next'
 16 | import { createForm } from '@formily/core'
 17 | import { FormProvider, createSchemaField } from '@formily/react'
 18 | 
 19 | const SchemaField = createSchemaField({
 20 |   components: {
 21 |     Password,
 22 |     FormItem,
 23 |   },
 24 | })
 25 | 
 26 | const form = createForm()
 27 | 
 28 | export default () => (
 29 |   <FormProvider form={form}>
 30 |     <FormLayout labelCol={6} wrapperCol={10}>
 31 |       <SchemaField>
 32 |         <SchemaField.String
 33 |           name="input"
 34 |           title="输入框"
 35 |           x-decorator="FormItem"
 36 |           x-component="Password"
 37 |           required
 38 |           x-component-props={{
 39 |             checkStrength: true,
 40 |           }}
 41 |         />
 42 |       </SchemaField>
 43 |       <FormButtonGroup.FormItem>
 44 |         <Submit onSubmit={console.log}>提交</Submit>
 45 |       </FormButtonGroup.FormItem>
 46 |     </FormLayout>
 47 |   </FormProvider>
 48 | )
 49 | ```
 50 | 
 51 | ## JSON Schema 案例
 52 | 
 53 | ```tsx
 54 | import React from 'react'
 55 | import {
 56 |   Password,
 57 |   FormItem,
 58 |   FormButtonGroup,
 59 |   Submit,
 60 |   FormLayout,
 61 | } from '@formily/next'
 62 | import { createForm } from '@formily/core'
 63 | import { FormProvider, createSchemaField } from '@formily/react'
 64 | const SchemaField = createSchemaField({
 65 |   components: {
 66 |     Password,
 67 |     FormItem,
 68 |   },
 69 | })
 70 | 
 71 | const form = createForm()
 72 | 
 73 | const schema = {
 74 |   type: 'object',
 75 |   properties: {
 76 |     input: {
 77 |       type: 'string',
 78 |       title: '输入框',
 79 |       'x-decorator': 'FormItem',
 80 |       'x-component': 'Password',
 81 |       'x-component-props': {
 82 |         checkStrength: true,
 83 |       },
 84 |     },
 85 |   },
 86 | }
 87 | 
 88 | export default () => (
 89 |   <FormProvider form={form}>
 90 |     <FormLayout labelCol={6} wrapperCol={10}>
 91 |       <SchemaField schema={schema} />
 92 |       <FormButtonGroup.FormItem>
 93 |         <Submit onSubmit={console.log}>提交</Submit>
 94 |       </FormButtonGroup.FormItem>
 95 |     </FormLayout>
 96 |   </FormProvider>
 97 | )
 98 | ```
 99 | 
100 | ## 纯 JSX 案例
101 | 
102 | ```tsx
103 | import React from 'react'
104 | import {
105 |   Password,
106 |   FormItem,
107 |   FormButtonGroup,
108 |   Submit,
109 |   FormLayout,
110 | } from '@formily/next'
111 | import { createForm } from '@formily/core'
112 | import { FormProvider, Field } from '@formily/react'
113 | const form = createForm()
114 | 
115 | export default () => (
116 |   <FormProvider form={form}>
117 |     <FormLayout labelCol={6} wrapperCol={10}>
118 |       <Field
119 |         name="input"
120 |         title="输入框"
121 |         required
122 |         decorator={[FormItem]}
123 |         component={[
124 |           Password,
125 |           {
126 |             checkStrength: true,
127 |           },
128 |         ]}
129 |       />
130 |       <FormButtonGroup.FormItem>
131 |         <Submit onSubmit={console.log}>提交</Submit>
132 |       </FormButtonGroup.FormItem>
133 |     </FormLayout>
134 |   </FormProvider>
135 | )
136 | ```
137 | 
138 | ## API
139 | 
140 | 参考 https://fusion.design/pc/component/basic/input
141 | 
```

--------------------------------------------------------------------------------
/packages/next/__tests__/sideEffects.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import SideEffectsFlagPlugin from 'webpack/lib/optimize/SideEffectsFlagPlugin'
 2 | // eslint-disable-next-line @typescript-eslint/no-var-requires
 3 | const { sideEffects, name: baseName } = require('../package.json')
 4 | 
 5 | test('sideEffects should be controlled manually', () => {
 6 |   // if config in pkg.json changed, please ensure it is covered by jest.
 7 |   expect(sideEffects).toStrictEqual([
 8 |     'dist/*',
 9 |     'esm/*.js',
10 |     'lib/*.js',
11 |     'src/*.ts',
12 |     '*.scss',
13 |     '**/*/style.js',
14 |   ])
15 | })
16 | 
17 | test('dist/*', () => {
18 |   // eg. import "@formily/next/dist/next.css"
19 |   expect(
20 |     SideEffectsFlagPlugin.moduleHasSideEffects('dist/next.css', 'dist/*')
21 |   ).toBeTruthy()
22 |   expect(
23 |     SideEffectsFlagPlugin.moduleHasSideEffects(
24 |       'dist/formily.next.umd.production.js',
25 |       'dist/*'
26 |     )
27 |   ).toBeTruthy()
28 |   expect(
29 |     SideEffectsFlagPlugin.moduleHasSideEffects(
30 |       'dist/formily.next.umd.production.js',
31 |       'dist/*'
32 |     )
33 |   ).toBeTruthy()
34 | })
35 | 
36 | test('esm/*.js & lib/*.js', () => {
37 |   // expected to be truthy
38 |   // eg. import Formilynext from "@formily/next/esm/index"
39 |   expect(
40 |     SideEffectsFlagPlugin.moduleHasSideEffects('esm/index.js', 'esm/*.js')
41 |   ).toBeTruthy()
42 |   expect(
43 |     SideEffectsFlagPlugin.moduleHasSideEffects('lib/index.js', 'lib/*.js')
44 |   ).toBeTruthy()
45 | 
46 |   // expected to be falsy
47 |   // eg. import Input from "@formily/next/esm/input/index" => will be compiled to __webpack_require__("./node_modules/@formily/next/esm/input/index.js")
48 |   // It should be removed by webpack if not used after imported.
49 |   expect(
50 |     SideEffectsFlagPlugin.moduleHasSideEffects('esm/input/index.js', 'esm/*.js')
51 |   ).toBeFalsy()
52 |   expect(
53 |     SideEffectsFlagPlugin.moduleHasSideEffects(
54 |       'esm/array-base/index.js',
55 |       'esm/*.js'
56 |     )
57 |   ).toBeFalsy()
58 |   expect(
59 |     SideEffectsFlagPlugin.moduleHasSideEffects('lib/input/index.js', 'lib/*.js')
60 |   ).toBeFalsy()
61 | })
62 | 
63 | test('*.scss', () => {
64 |   //  eg. import "@formily/next/lib/input/style.scss"
65 |   expect(
66 |     SideEffectsFlagPlugin.moduleHasSideEffects(
67 |       `${baseName}/lib/input/style.scss`,
68 |       '*.scss'
69 |     )
70 |   ).toBeTruthy()
71 | })
72 | 
73 | test('**/*/style.js', () => {
74 |   // eg. import "@formily/next/lib/input/style" will be compiled to  __webpack_require__("./node_modules/@formily/next/lib/input/style.js")
75 |   // so we can match the `*style.js` only, not `**/*/style*` may be cause someting mismatch like `@formily/next/lib/xxx-style/index.js`
76 |   const modulePathArr = [
77 |     'lib/input/style.js',
78 |     `${baseName}/lib/input/style.js`,
79 |     `./node_modules/${baseName}/style.js`,
80 |   ]
81 | 
82 |   modulePathArr.forEach((modulePath) => {
83 |     const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(
84 |       modulePath,
85 |       '**/*/style.js'
86 |     )
87 |     expect(hasSideEffects).toBeTruthy()
88 |   })
89 | })
90 | 
```

--------------------------------------------------------------------------------
/packages/antd/__tests__/sideEffects.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import SideEffectsFlagPlugin from 'webpack/lib/optimize/SideEffectsFlagPlugin'
 2 | // eslint-disable-next-line @typescript-eslint/no-var-requires
 3 | const { sideEffects, name: baseName } = require('../package.json')
 4 | 
 5 | test('sideEffects should be controlled manually', () => {
 6 |   // if config in pkg.json changed, please ensure it is covered by jest.
 7 |   expect(sideEffects).toStrictEqual([
 8 |     'dist/*',
 9 |     'esm/*.js',
10 |     'lib/*.js',
11 |     'src/*.ts',
12 |     '*.less',
13 |     '**/*/style.js',
14 |   ])
15 | })
16 | 
17 | test('dist/*', () => {
18 |   // eg. import "@formily/antd/dist/antd.css"
19 |   expect(
20 |     SideEffectsFlagPlugin.moduleHasSideEffects('dist/antd.css', 'dist/*')
21 |   ).toBeTruthy()
22 |   expect(
23 |     SideEffectsFlagPlugin.moduleHasSideEffects(
24 |       'dist/formily.antd.umd.development.js',
25 |       'dist/*'
26 |     )
27 |   ).toBeTruthy()
28 |   expect(
29 |     SideEffectsFlagPlugin.moduleHasSideEffects(
30 |       'dist/formily.antd.umd.production.js',
31 |       'dist/*'
32 |     )
33 |   ).toBeTruthy()
34 | })
35 | 
36 | test('esm/*.js & lib/*.js', () => {
37 |   // expected to be truthy
38 |   // eg. import FormilyAntd from "@formily/antd/esm/index"
39 |   expect(
40 |     SideEffectsFlagPlugin.moduleHasSideEffects('esm/index.js', 'esm/*.js')
41 |   ).toBeTruthy()
42 |   expect(
43 |     SideEffectsFlagPlugin.moduleHasSideEffects('lib/index.js', 'lib/*.js')
44 |   ).toBeTruthy()
45 | 
46 |   // expected to be falsy
47 |   // eg. import Input from "@formily/antd/esm/input/index" => will be compiled to __webpack_require__("./node_modules/@formily/antd/esm/input/index.js")
48 |   // It should be removed by webpack if not used after imported.
49 |   expect(
50 |     SideEffectsFlagPlugin.moduleHasSideEffects('esm/input/index.js', 'esm/*.js')
51 |   ).toBeFalsy()
52 |   expect(
53 |     SideEffectsFlagPlugin.moduleHasSideEffects(
54 |       'esm/array-base/index.js',
55 |       'esm/*.js'
56 |     )
57 |   ).toBeFalsy()
58 |   expect(
59 |     SideEffectsFlagPlugin.moduleHasSideEffects('lib/input/index.js', 'lib/*.js')
60 |   ).toBeFalsy()
61 | })
62 | 
63 | test('*.less', () => {
64 |   //  eg. import "@formily/antd/lib/input/style.less"
65 |   expect(
66 |     SideEffectsFlagPlugin.moduleHasSideEffects(
67 |       `${baseName}/lib/input/style.less`,
68 |       '*.less'
69 |     )
70 |   ).toBeTruthy()
71 | })
72 | 
73 | test('**/*/style.js', () => {
74 |   // eg. import "@formily/antd/lib/input/style" will be compiled to  __webpack_require__("./node_modules/@formily/antd/lib/input/style.js")
75 |   // so we can match the `*style.js` only, not `**/*/style*` may be cause someting mismatch like `@formily/antd/lib/xxx-style/index.js`
76 |   const modulePathArr = [
77 |     'lib/input/style.js',
78 |     `${baseName}/lib/input/style.js`,
79 |     `./node_modules/${baseName}/style.js`,
80 |   ]
81 | 
82 |   modulePathArr.forEach((modulePath) => {
83 |     const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(
84 |       modulePath,
85 |       '**/*/style.js'
86 |     )
87 |     expect(hasSideEffects).toBeTruthy()
88 |   })
89 | })
90 | 
```

--------------------------------------------------------------------------------
/packages/core/src/__tests__/internals.spec.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   getValuesFromEvent,
  3 |   matchFeedback,
  4 |   patchFieldStates,
  5 |   deserialize,
  6 |   isHTMLInputEvent,
  7 | } from '../shared/internals'
  8 | import { createForm } from '../'
  9 | import { attach } from './shared'
 10 | 
 11 | test('getValuesFromEvent', () => {
 12 |   expect(getValuesFromEvent([{ target: { value: 123 } }])).toEqual([123])
 13 |   expect(getValuesFromEvent([{ target: { checked: true } }])).toEqual([true])
 14 |   expect(getValuesFromEvent([{ target: {} }])).toEqual([undefined])
 15 |   expect(getValuesFromEvent([{ target: null }])).toEqual([{ target: null }])
 16 |   expect(getValuesFromEvent([123])).toEqual([123])
 17 |   expect(getValuesFromEvent([null])).toEqual([null])
 18 | })
 19 | 
 20 | test('empty', () => {
 21 |   expect(matchFeedback()).toBeFalsy()
 22 | })
 23 | 
 24 | test('patchFieldStates', () => {
 25 |   const fields = {}
 26 |   patchFieldStates(fields, [{ type: 'update', address: 'aaa', payload: null }])
 27 |   patchFieldStates(fields, [
 28 |     { type: 'update3' as any, address: 'aaa', payload: null },
 29 |   ])
 30 |   expect(fields).toEqual({})
 31 | })
 32 | 
 33 | test('patchFieldStates should be sequence', () => {
 34 |   const form = attach(createForm())
 35 |   attach(
 36 |     form.createArrayField({
 37 |       name: 'array',
 38 |     })
 39 |   )
 40 |   attach(
 41 |     form.createField({
 42 |       name: 'input',
 43 |       basePath: 'array.0',
 44 |     })
 45 |   )
 46 |   attach(
 47 |     form.createField({
 48 |       name: 'input',
 49 |       basePath: 'array.1',
 50 |     })
 51 |   )
 52 |   const before = Object.keys(form.fields)
 53 |   form.fields['array'].move(1, 0)
 54 |   const after = Object.keys(form.fields)
 55 |   expect(after).toEqual(before)
 56 | 
 57 |   const form2 = attach(createForm())
 58 |   attach(
 59 |     form2.createField({
 60 |       name: 'field1',
 61 |       title: 'Field 1',
 62 |     })
 63 |   )
 64 |   attach(
 65 |     form2.createField({
 66 |       name: 'field2',
 67 |       title: 'Field 1',
 68 |     })
 69 |   )
 70 | 
 71 |   patchFieldStates(form2.fields, [
 72 |     {
 73 |       type: 'update',
 74 |       address: 'field2',
 75 |       oldAddress: 'field1',
 76 |       payload: form2.field1,
 77 |     },
 78 |     {
 79 |       type: 'update',
 80 |       address: 'field1',
 81 |       oldAddress: 'field2',
 82 |       payload: form2.field2,
 83 |     },
 84 |   ])
 85 | 
 86 |   expect(Object.keys(form2.fields)).toEqual(['field1', 'field2'])
 87 | })
 88 | 
 89 | test('deserialize', () => {
 90 |   expect(deserialize(null, null)).toBeUndefined()
 91 |   expect(
 92 |     deserialize(
 93 |       {},
 94 |       {
 95 |         parent: null,
 96 |       }
 97 |     )
 98 |   ).toEqual({})
 99 | })
100 | 
101 | test('isHTMLInputEvent', () => {
102 |   expect(isHTMLInputEvent({ target: { checked: true } })).toBeTruthy()
103 |   expect(isHTMLInputEvent({ target: { value: 123 } })).toBeTruthy()
104 |   expect(
105 |     isHTMLInputEvent({ target: { tagName: 'INPUT', value: null } })
106 |   ).toBeTruthy()
107 |   expect(isHTMLInputEvent({ target: { tagName: 'INPUT' } })).toBeFalsy()
108 |   expect(isHTMLInputEvent({ target: { tagName: 'DIV' } })).toBeFalsy()
109 |   expect(isHTMLInputEvent({ target: {}, stopPropagation() {} })).toBeFalsy()
110 |   expect(isHTMLInputEvent({})).toBeFalsy()
111 | })
112 | 
```

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

```markdown
  1 | # Password
  2 | 
  3 | > Password input box
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import {
 10 |   Password,
 11 |   FormItem,
 12 |   FormLayout,
 13 |   FormButtonGroup,
 14 |   Submit,
 15 | } from '@formily/antd'
 16 | import { createForm } from '@formily/core'
 17 | import { FormProvider, createSchemaField } from '@formily/react'
 18 | 
 19 | const SchemaField = createSchemaField({
 20 |   components: {
 21 |     Password,
 22 |     FormItem,
 23 |   },
 24 | })
 25 | 
 26 | const form = createForm()
 27 | 
 28 | export default () => (
 29 |   <FormProvider form={form}>
 30 |     <FormLayout labelCol={6} wrapperCol={10}>
 31 |       <SchemaField>
 32 |         <SchemaField.String
 33 |           name="input"
 34 |           title="input box"
 35 |           x-decorator="FormItem"
 36 |           x-component="Password"
 37 |           required
 38 |           x-component-props={{
 39 |             checkStrength: true,
 40 |           }}
 41 |         />
 42 |       </SchemaField>
 43 |       <FormButtonGroup.FormItem>
 44 |         <Submit onSubmit={console.log}>Submit</Submit>
 45 |       </FormButtonGroup.FormItem>
 46 |     </FormLayout>
 47 |   </FormProvider>
 48 | )
 49 | ```
 50 | 
 51 | ## JSON Schema case
 52 | 
 53 | ```tsx
 54 | import React from 'react'
 55 | import {
 56 |   Password,
 57 |   FormItem,
 58 |   FormLayout,
 59 |   FormButtonGroup,
 60 |   Submit,
 61 | } from '@formily/antd'
 62 | import { createForm } from '@formily/core'
 63 | import { FormProvider, createSchemaField } from '@formily/react'
 64 | 
 65 | const SchemaField = createSchemaField({
 66 |   components: {
 67 |     Password,
 68 |     FormItem,
 69 |   },
 70 | })
 71 | 
 72 | const form = createForm()
 73 | 
 74 | const schema = {
 75 |   type: 'object',
 76 |   properties: {
 77 |     input: {
 78 |       type: 'string',
 79 |       title: 'input box',
 80 |       'x-decorator': 'FormItem',
 81 |       'x-component': 'Password',
 82 |       'x-component-props': {
 83 |         checkStrength: true,
 84 |       },
 85 |     },
 86 |   },
 87 | }
 88 | 
 89 | export default () => (
 90 |   <FormProvider form={form}>
 91 |     <FormLayout labelCol={6} wrapperCol={10}>
 92 |       <SchemaField schema={schema} />
 93 |       <FormButtonGroup.FormItem>
 94 |         <Submit onSubmit={console.log}>Submit</Submit>
 95 |       </FormButtonGroup.FormItem>
 96 |     </FormLayout>
 97 |   </FormProvider>
 98 | )
 99 | ```
100 | 
101 | ## Pure JSX case
102 | 
103 | ```tsx
104 | import React from 'react'
105 | import {
106 |   Password,
107 |   FormItem,
108 |   FormLayout,
109 |   FormButtonGroup,
110 |   Submit,
111 | } from '@formily/antd'
112 | import { createForm } from '@formily/core'
113 | import { FormProvider, Field } from '@formily/react'
114 | const form = createForm()
115 | 
116 | export default () => (
117 |   <FormProvider form={form}>
118 |     <FormLayout labelCol={6} wrapperCol={10}>
119 |       <Field
120 |         name="input"
121 |         title="input box"
122 |         required
123 |         decorator={[FormItem]}
124 |         component={[
125 |           Password,
126 |           {
127 |             checkStrength: true,
128 |           },
129 |         ]}
130 |       />
131 |       <FormButtonGroup.FormItem>
132 |         <Submit onSubmit={console.log}>Submit</Submit>
133 |       </FormButtonGroup.FormItem>
134 |     </FormLayout>
135 |   </FormProvider>
136 | )
137 | ```
138 | 
139 | ## API
140 | 
141 | Reference https://ant.design/components/input-cn/
142 | 
```

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

```markdown
  1 | # Transfer
  2 | 
  3 | > Shuttle Box
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 10 | import { createForm } from '@formily/core'
 11 | import { FormProvider, createSchemaField } from '@formily/react'
 12 | 
 13 | const SchemaField = createSchemaField({
 14 |   components: {
 15 |     Transfer,
 16 |     FormItem,
 17 |   },
 18 | })
 19 | 
 20 | const form = createForm()
 21 | 
 22 | export default () => (
 23 |   <FormProvider form={form}>
 24 |     <SchemaField>
 25 |       <SchemaField.Array
 26 |         name="transfer"
 27 |         title="shuttle box"
 28 |         x-decorator="FormItem"
 29 |         x-component="Transfer"
 30 |         enum={[
 31 |           { title: 'Option 1', key: 1 },
 32 |           { title: 'Option 2', key: 2 },
 33 |         ]}
 34 |         x-component-props={{
 35 |           render: (item) => item.title,
 36 |         }}
 37 |       />
 38 |     </SchemaField>
 39 |     <FormButtonGroup>
 40 |       <Submit onSubmit={console.log}>Submit</Submit>
 41 |     </FormButtonGroup>
 42 |   </FormProvider>
 43 | )
 44 | ```
 45 | 
 46 | ## JSON Schema case
 47 | 
 48 | ```tsx
 49 | import React from 'react'
 50 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 51 | import { createForm } from '@formily/core'
 52 | import { FormProvider, createSchemaField } from '@formily/react'
 53 | 
 54 | const SchemaField = createSchemaField({
 55 |   components: {
 56 |     Transfer,
 57 |     FormItem,
 58 |   },
 59 | })
 60 | 
 61 | const form = createForm()
 62 | 
 63 | const schema = {
 64 |   type: 'object',
 65 |   properties: {
 66 |     transfer: {
 67 |       type: 'array',
 68 |       title: 'shuttle box',
 69 |       'x-decorator': 'FormItem',
 70 |       'x-component': 'Transfer',
 71 |       enum: [
 72 |         { title: 'Option 1', key: 1 },
 73 |         { title: 'Option 2', key: 2 },
 74 |       ],
 75 |       'x-component-props': {
 76 |         render: '{{renderTitle}}',
 77 |       },
 78 |     },
 79 |   },
 80 | }
 81 | 
 82 | const renderTitle = (item) => item.title
 83 | 
 84 | export default () => (
 85 |   <FormProvider form={form}>
 86 |     <SchemaField schema={schema} scope={{ renderTitle }} />
 87 |     <FormButtonGroup>
 88 |       <Submit onSubmit={console.log}>Submit</Submit>
 89 |     </FormButtonGroup>
 90 |   </FormProvider>
 91 | )
 92 | ```
 93 | 
 94 | ## Pure JSX case
 95 | 
 96 | ```tsx
 97 | import React from 'react'
 98 | import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'
 99 | import { createForm } from '@formily/core'
100 | import { FormProvider, Field } from '@formily/react'
101 | 
102 | const form = createForm()
103 | 
104 | export default () => (
105 |   <FormProvider form={form}>
106 |     <Field
107 |       name="transfer"
108 |       title="shuttle box"
109 |       dataSource={[
110 |         { title: 'Option 1', key: 1 },
111 |         { title: 'Option 2', key: 2 },
112 |       ]}
113 |       decorator={[FormItem]}
114 |       component={[
115 |         Transfer,
116 |         {
117 |           render: (item) => item.title,
118 |         },
119 |       ]}
120 |     />
121 |     <FormButtonGroup>
122 |       <Submit onSubmit={console.log}>Submit</Submit>
123 |     </FormButtonGroup>
124 |   </FormProvider>
125 | )
126 | ```
127 | 
128 | ## API
129 | 
130 | Reference https://ant.design/components/transfer-cn/
131 | 
```

--------------------------------------------------------------------------------
/packages/reactive/src/__tests__/collections-weakmap.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { observable, autorun, raw } from '..'
 2 | 
 3 | describe('WeakMap', () => {
 4 |   test('should be a proper JS WeakMap', () => {
 5 |     const weakMap = observable(new WeakMap())
 6 |     expect(weakMap).toBeInstanceOf(WeakMap)
 7 |     expect(raw(weakMap)).toBeInstanceOf(WeakMap)
 8 |   })
 9 | 
10 |   test('should autorun mutations', () => {
11 |     const handler = jest.fn()
12 |     const key = {}
13 |     const weakMap = observable(new WeakMap())
14 |     autorun(() => handler(weakMap.get(key)))
15 | 
16 |     expect(handler).toBeCalledTimes(1)
17 |     expect(handler).lastCalledWith(undefined)
18 |     weakMap.set(key, 'value')
19 |     expect(handler).toBeCalledTimes(2)
20 |     expect(handler).lastCalledWith('value')
21 |     weakMap.set(key, 'value2')
22 |     expect(handler).toBeCalledTimes(3)
23 |     expect(handler).lastCalledWith('value2')
24 |     weakMap.delete(key)
25 |     expect(handler).toBeCalledTimes(4)
26 |     expect(handler).lastCalledWith(undefined)
27 |   })
28 | 
29 |   test('should not autorun custom property mutations', () => {
30 |     const handler = jest.fn()
31 |     const weakMap = observable(new WeakMap())
32 |     autorun(() => handler(weakMap['customProp']))
33 | 
34 |     expect(handler).toBeCalledTimes(1)
35 |     expect(handler).lastCalledWith(undefined)
36 |     weakMap['customProp'] = 'Hello World'
37 |     expect(handler).toBeCalledTimes(1)
38 |   })
39 | 
40 |   test('should not autorun non value changing mutations', () => {
41 |     const handler = jest.fn()
42 |     const key = {}
43 |     const weakMap = observable(new WeakMap())
44 |     autorun(() => handler(weakMap.get(key)))
45 | 
46 |     expect(handler).toBeCalledTimes(1)
47 |     expect(handler).lastCalledWith(undefined)
48 |     weakMap.set(key, 'value')
49 |     expect(handler).toBeCalledTimes(2)
50 |     expect(handler).lastCalledWith('value')
51 |     weakMap.set(key, 'value')
52 |     expect(handler).toBeCalledTimes(2)
53 |     weakMap.delete(key)
54 |     expect(handler).toBeCalledTimes(3)
55 |     expect(handler).lastCalledWith(undefined)
56 |     weakMap.delete(key)
57 |     expect(handler).toBeCalledTimes(3)
58 |   })
59 | 
60 |   test('should not autorun raw data', () => {
61 |     const handler = jest.fn()
62 |     const key = {}
63 |     const weakMap = observable(new WeakMap())
64 |     autorun(() => handler(raw(weakMap).get(key)))
65 | 
66 |     expect(handler).toBeCalledTimes(1)
67 |     expect(handler).lastCalledWith(undefined)
68 |     weakMap.set(key, 'Hello')
69 |     expect(handler).toBeCalledTimes(1)
70 |     weakMap.delete(key)
71 |     expect(handler).toBeCalledTimes(1)
72 |   })
73 | 
74 |   test('should not be triggered by raw mutations', () => {
75 |     const handler = jest.fn()
76 |     const key = {}
77 |     const weakMap = observable(new WeakMap())
78 |     autorun(() => handler(weakMap.get(key)))
79 | 
80 |     expect(handler).toBeCalledTimes(1)
81 |     expect(handler).lastCalledWith(undefined)
82 |     raw(weakMap).set(key, 'Hello')
83 |     expect(handler).toBeCalledTimes(1)
84 |     raw(weakMap).delete(key)
85 |     expect(handler).toBeCalledTimes(1)
86 |   })
87 | })
88 | 
```

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

```markdown
  1 | # Password
  2 | 
  3 | > Password input box
  4 | 
  5 | ## Markup Schema example
  6 | 
  7 | ```tsx
  8 | import React from 'react'
  9 | import {
 10 |   Password,
 11 |   FormItem,
 12 |   FormButtonGroup,
 13 |   Submit,
 14 |   FormLayout,
 15 | } from '@formily/next'
 16 | import { createForm } from '@formily/core'
 17 | import { FormProvider, createSchemaField } from '@formily/react'
 18 | 
 19 | const SchemaField = createSchemaField({
 20 |   components: {
 21 |     Password,
 22 |     FormItem,
 23 |   },
 24 | })
 25 | 
 26 | const form = createForm()
 27 | 
 28 | export default () => (
 29 |   <FormProvider form={form}>
 30 |     <FormLayout labelCol={6} wrapperCol={10}>
 31 |       <SchemaField>
 32 |         <SchemaField.String
 33 |           name="input"
 34 |           title="input box"
 35 |           x-decorator="FormItem"
 36 |           x-component="Password"
 37 |           required
 38 |           x-component-props={{
 39 |             checkStrength: true,
 40 |           }}
 41 |         />
 42 |       </SchemaField>
 43 |       <FormButtonGroup.FormItem>
 44 |         <Submit onSubmit={console.log}>Submit</Submit>
 45 |       </FormButtonGroup.FormItem>
 46 |     </FormLayout>
 47 |   </FormProvider>
 48 | )
 49 | ```
 50 | 
 51 | ## JSON Schema case
 52 | 
 53 | ```tsx
 54 | import React from 'react'
 55 | import {
 56 |   Password,
 57 |   FormItem,
 58 |   FormButtonGroup,
 59 |   Submit,
 60 |   FormLayout,
 61 | } from '@formily/next'
 62 | import { createForm } from '@formily/core'
 63 | import { FormProvider, createSchemaField } from '@formily/react'
 64 | const SchemaField = createSchemaField({
 65 |   components: {
 66 |     Password,
 67 |     FormItem,
 68 |   },
 69 | })
 70 | 
 71 | const form = createForm()
 72 | 
 73 | const schema = {
 74 |   type: 'object',
 75 |   properties: {
 76 |     input: {
 77 |       type: 'string',
 78 |       title: 'input box',
 79 |       'x-decorator': 'FormItem',
 80 |       'x-component': 'Password',
 81 |       'x-component-props': {
 82 |         checkStrength: true,
 83 |       },
 84 |     },
 85 |   },
 86 | }
 87 | 
 88 | export default () => (
 89 |   <FormProvider form={form}>
 90 |     <FormLayout labelCol={6} wrapperCol={10}>
 91 |       <SchemaField schema={schema} />
 92 |       <FormButtonGroup.FormItem>
 93 |         <Submit onSubmit={console.log}>Submit</Submit>
 94 |       </FormButtonGroup.FormItem>
 95 |     </FormLayout>
 96 |   </FormProvider>
 97 | )
 98 | ```
 99 | 
100 | ## Pure JSX case
101 | 
102 | ```tsx
103 | import React from 'react'
104 | import {
105 |   Password,
106 |   FormItem,
107 |   FormButtonGroup,
108 |   Submit,
109 |   FormLayout,
110 | } from '@formily/next'
111 | import { createForm } from '@formily/core'
112 | import { FormProvider, Field } from '@formily/react'
113 | const form = createForm()
114 | 
115 | export default () => (
116 |   <FormProvider form={form}>
117 |     <FormLayout labelCol={6} wrapperCol={10}>
118 |       <Field
119 |         name="input"
120 |         title="input box"
121 |         required
122 |         decorator={[FormItem]}
123 |         component={[
124 |           Password,
125 |           {
126 |             checkStrength: true,
127 |           },
128 |         ]}
129 |       />
130 |       <FormButtonGroup.FormItem>
131 |         <Submit onSubmit={console.log}>Submit</Submit>
132 |       </FormButtonGroup.FormItem>
133 |     </FormLayout>
134 |   </FormProvider>
135 | )
136 | ```
137 | 
138 | ## API
139 | 
140 | Reference https://fusion.design/pc/component/basic/input
141 | 
```

--------------------------------------------------------------------------------
/packages/json-schema/src/__tests__/server-validate.spec.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { createForm, Form } from '@formily/core'
  2 | import { ISchema, Schema, SchemaKey } from '../'
  3 | 
  4 | // 这是schema
  5 | const schemaJson = {
  6 |   type: 'object',
  7 |   title: 'xxx配置',
  8 |   properties: {
  9 |     string: {
 10 |       type: 'string',
 11 |       title: 'string',
 12 |       maxLength: 5,
 13 |       required: true,
 14 |     },
 15 |     number: {
 16 |       type: 'number',
 17 |       title: 'number',
 18 |       required: true,
 19 |     },
 20 |     url: {
 21 |       type: 'string',
 22 |       title: 'url',
 23 |       format: 'url',
 24 |     },
 25 |     arr: {
 26 |       type: 'array',
 27 |       title: 'array',
 28 |       maxItems: 2,
 29 |       required: true,
 30 |       items: {
 31 |         type: 'object',
 32 |         properties: {
 33 |           string: {
 34 |             type: 'string',
 35 |             title: 'string',
 36 |             required: true,
 37 |           },
 38 |         },
 39 |       },
 40 |     },
 41 |   },
 42 | }
 43 | // 这是需要校验的数据
 44 | const schemaData = {
 45 |   string: '123456', // 超过5个字
 46 |   // number 字段不存在
 47 |   url: 'xxxxx', // 不合法的url
 48 |   arr: [
 49 |     {
 50 |       string: '1',
 51 |     },
 52 |     {
 53 |       string: '2',
 54 |     },
 55 |     {
 56 |       // 数组超出2项
 57 |       string: '', // 没有填
 58 |     },
 59 |   ],
 60 | }
 61 | 
 62 | function recursiveField(
 63 |   form: Form,
 64 |   schema: ISchema,
 65 |   basePath?: string,
 66 |   name?: SchemaKey
 67 | ) {
 68 |   const fieldSchema = new Schema(schema)
 69 |   const fieldProps = fieldSchema.toFieldProps()
 70 | 
 71 |   function recursiveProperties(propBasePath?: string) {
 72 |     fieldSchema.mapProperties((propSchema, propName) => {
 73 |       recursiveField(form, propSchema, propBasePath, propName)
 74 |     })
 75 |   }
 76 | 
 77 |   if (name === undefined || name === null) {
 78 |     recursiveProperties(basePath)
 79 |     return
 80 |   }
 81 | 
 82 |   if (schema.type === 'object') {
 83 |     const field = form.createObjectField({
 84 |       ...fieldProps,
 85 |       name,
 86 |       basePath,
 87 |     })
 88 | 
 89 |     recursiveProperties(field.address.toString())
 90 |   } else if (schema.type === 'array') {
 91 |     const field = form.createArrayField({
 92 |       ...fieldProps,
 93 |       name,
 94 |       basePath,
 95 |     })
 96 | 
 97 |     const fieldAddress = field.address.toString()
 98 |     const fieldValues = form.getValuesIn(fieldAddress)
 99 |     fieldValues.forEach((value: any, index: number) => {
100 |       if (schema.items) {
101 |         const itemsSchema = Array.isArray(schema.items)
102 |           ? schema.items[index] || schema.items[0]
103 |           : schema.items
104 | 
105 |         recursiveField(form, itemsSchema as ISchema, fieldAddress, index)
106 |       }
107 |     })
108 |   } else if (schema.type === 'void') {
109 |     const field = form.createVoidField({
110 |       ...fieldProps,
111 |       name,
112 |       basePath,
113 |     })
114 | 
115 |     recursiveProperties(field.address.toString())
116 |   } else {
117 |     form.createField({
118 |       ...fieldProps,
119 |       name,
120 |       basePath,
121 |     })
122 |   }
123 | }
124 | test('server validate', async () => {
125 |   const form = createForm({
126 |     values: schemaData,
127 |   })
128 |   recursiveField(form, schemaJson)
129 |   let errors: any[]
130 |   try {
131 |     await form.validate()
132 |   } catch (e) {
133 |     errors = e
134 |   }
135 |   expect(errors).not.toBeUndefined()
136 | })
137 | 
```

--------------------------------------------------------------------------------
/packages/core/src/shared/checkers.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { isFn } from '@formily/shared'
  2 | import { DataField, JSXComponent } from '..'
  3 | import {
  4 |   Form,
  5 |   Field,
  6 |   ArrayField,
  7 |   ObjectField,
  8 |   VoidField,
  9 |   Query,
 10 | } from '../models'
 11 | import {
 12 |   IFormState,
 13 |   IFieldState,
 14 |   IVoidFieldState,
 15 |   GeneralField,
 16 |   IGeneralFieldState,
 17 | } from '../types'
 18 | 
 19 | export const isForm = (node: any): node is Form => {
 20 |   return node instanceof Form
 21 | }
 22 | 
 23 | export const isGeneralField = (node: any): node is GeneralField => {
 24 |   return node instanceof Field || node instanceof VoidField
 25 | }
 26 | 
 27 | export const isField = <
 28 |   Decorator extends JSXComponent = any,
 29 |   Component extends JSXComponent = any,
 30 |   TextType = any,
 31 |   ValueType = any
 32 | >(
 33 |   node: any
 34 | ): node is Field<Decorator, Component, TextType, ValueType> => {
 35 |   return node instanceof Field
 36 | }
 37 | 
 38 | export const isArrayField = <
 39 |   Decorator extends JSXComponent = any,
 40 |   Component extends JSXComponent = any
 41 | >(
 42 |   node: any
 43 | ): node is ArrayField<Decorator, Component> => {
 44 |   return node instanceof ArrayField
 45 | }
 46 | 
 47 | export const isObjectField = <
 48 |   Decorator extends JSXComponent = any,
 49 |   Component extends JSXComponent = any
 50 | >(
 51 |   node: any
 52 | ): node is ObjectField<Decorator, Component> => {
 53 |   return node instanceof ObjectField
 54 | }
 55 | 
 56 | export const isVoidField = <Decorator = any, Component = any, TextType = any>(
 57 |   node: any
 58 | ): node is VoidField<Decorator, Component, TextType> => {
 59 |   return node instanceof VoidField
 60 | }
 61 | 
 62 | export const isFormState = <T extends Record<any, any> = any>(
 63 |   state: any
 64 | ): state is IFormState<T> => {
 65 |   if (isFn(state?.initialize)) return false
 66 |   return state?.displayName === 'Form'
 67 | }
 68 | 
 69 | export const isFieldState = (state: any): state is IFieldState => {
 70 |   if (isFn(state?.initialize)) return false
 71 |   return state?.displayName === 'Field'
 72 | }
 73 | 
 74 | export const isGeneralFieldState = (node: any): node is IGeneralFieldState => {
 75 |   if (isFn(node?.initialize)) return false
 76 |   return node?.displayName?.indexOf('Field') > -1
 77 | }
 78 | 
 79 | export const isArrayFieldState = (state: any): state is IFieldState => {
 80 |   if (isFn(state?.initialize)) return false
 81 |   return state?.displayName === 'ArrayField'
 82 | }
 83 | 
 84 | export const isDataField = (node: any): node is DataField => {
 85 |   return isField(node) || isArrayField(node) || isObjectField(node)
 86 | }
 87 | 
 88 | export const isDataFieldState = (node: any) => {
 89 |   return (
 90 |     isFieldState(node) || isObjectFieldState(node) || isArrayFieldState(node)
 91 |   )
 92 | }
 93 | 
 94 | export const isObjectFieldState = (state: any): state is IFieldState => {
 95 |   if (isFn(state?.initialize)) return false
 96 |   return state?.displayName === 'ObjectField'
 97 | }
 98 | 
 99 | export const isVoidFieldState = (state: any): state is IVoidFieldState => {
100 |   if (isFn(state?.initialize)) return false
101 |   return state?.displayName === 'VoidField'
102 | }
103 | 
104 | export const isQuery = (query: any): query is Query => {
105 |   return query && query instanceof Query
106 | }
107 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/form-tab/json-schema.vue:
--------------------------------------------------------------------------------

```vue
  1 | <template>
  2 |   <FormProvider :form="form">
  3 |     <SchemaField :schema="schema" :scope="{ formTab }" />
  4 |     <FormButtonGroup alignFormItem>
  5 |       <Button
  6 |         @click="
  7 |           () => {
  8 |             form.query('tab3').take((field) => {
  9 |               field.visible = !field.visible
 10 |             })
 11 |           }
 12 |         "
 13 |       >
 14 |         显示/隐藏最后一个Tab
 15 |       </Button>
 16 |       <Button
 17 |         @click="
 18 |           () => {
 19 |             formTab.setActiveKey('tab2')
 20 |           }
 21 |         "
 22 |       >
 23 |         切换第二个Tab
 24 |       </Button>
 25 |       <Submit @submit="log">提交</Submit>
 26 |     </FormButtonGroup>
 27 |   </FormProvider>
 28 | </template>
 29 | 
 30 | <script>
 31 | import { createForm } from '@formily/core'
 32 | import { FormProvider, createSchemaField } from '@formily/vue'
 33 | import {
 34 |   FormItem,
 35 |   FormTab,
 36 |   FormButtonGroup,
 37 |   Submit,
 38 |   Input,
 39 | } from '@formily/element'
 40 | import { Button } from 'element-ui'
 41 | 
 42 | const { SchemaField } = createSchemaField({
 43 |   components: {
 44 |     FormItem,
 45 |     FormTab,
 46 |     Input,
 47 |   },
 48 | })
 49 | 
 50 | const schema = {
 51 |   type: 'object',
 52 |   properties: {
 53 |     collapse: {
 54 |       type: 'void',
 55 |       'x-component': 'FormTab',
 56 |       'x-component-props': {
 57 |         formTab: '{{formTab}}',
 58 |       },
 59 |       properties: {
 60 |         tab1: {
 61 |           type: 'void',
 62 |           'x-component': 'FormTab.TabPane',
 63 |           'x-component-props': {
 64 |             label: 'A1',
 65 |           },
 66 |           properties: {
 67 |             aaa: {
 68 |               type: 'string',
 69 |               title: 'AAA',
 70 |               'x-decorator': 'FormItem',
 71 |               required: true,
 72 |               'x-component': 'Input',
 73 |             },
 74 |           },
 75 |         },
 76 |         tab2: {
 77 |           type: 'void',
 78 |           'x-component': 'FormTab.TabPane',
 79 |           'x-component-props': {
 80 |             label: 'A2',
 81 |           },
 82 |           properties: {
 83 |             bbb: {
 84 |               type: 'string',
 85 |               title: 'BBB',
 86 |               'x-decorator': 'FormItem',
 87 |               required: true,
 88 |               'x-component': 'Input',
 89 |             },
 90 |           },
 91 |         },
 92 |         tab3: {
 93 |           type: 'void',
 94 |           'x-component': 'FormTab.TabPane',
 95 |           'x-component-props': {
 96 |             label: 'A3',
 97 |           },
 98 |           properties: {
 99 |             ccc: {
100 |               type: 'string',
101 |               title: 'CCC',
102 |               'x-decorator': 'FormItem',
103 |               required: true,
104 |               'x-component': 'Input',
105 |             },
106 |           },
107 |         },
108 |       },
109 |     },
110 |   },
111 | }
112 | 
113 | export default {
114 |   components: {
115 |     FormProvider,
116 |     FormButtonGroup,
117 |     Button,
118 |     Submit,
119 |     SchemaField,
120 |   },
121 | 
122 |   data() {
123 |     const form = createForm()
124 |     const formTab = FormTab.createFormTab()
125 | 
126 |     return {
127 |       schema,
128 |       form,
129 |       formTab,
130 |     }
131 |   },
132 |   methods: {
133 |     log(values) {
134 |       console.log(values)
135 |     },
136 |   },
137 | }
138 | </script>
139 | 
140 | <style lang="scss" scoped></style>
141 | 
```

--------------------------------------------------------------------------------
/packages/next/src/__builtins__/empty.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import React from 'react'
 2 | 
 3 | export const Empty = () => {
 4 |   return (
 5 |     <div className="next-empty">
 6 |       <div className="next-empty-image">
 7 |         <svg
 8 |           className="ant-empty-img-default"
 9 |           width="184"
10 |           height="120"
11 |           viewBox="0 0 184 152"
12 |           xmlns="http://www.w3.org/2000/svg"
13 |         >
14 |           <g fill="none" fillRule="evenodd">
15 |             <g transform="translate(24 31.67)">
16 |               <ellipse
17 |                 className="ant-empty-img-default-ellipse"
18 |                 cx="67.797"
19 |                 cy="106.89"
20 |                 rx="67.797"
21 |                 ry="12.668"
22 |               ></ellipse>
23 |               <path
24 |                 className="ant-empty-img-default-path-1"
25 |                 d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
26 |               ></path>
27 |               <path
28 |                 className="ant-empty-img-default-path-2"
29 |                 d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z"
30 |                 transform="translate(13.56)"
31 |               ></path>
32 |               <path
33 |                 className="ant-empty-img-default-path-3"
34 |                 d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
35 |               ></path>
36 |               <path
37 |                 className="ant-empty-img-default-path-4"
38 |                 d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
39 |               ></path>
40 |             </g>
41 |             <path
42 |               className="ant-empty-img-default-path-5"
43 |               d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
44 |             ></path>
45 |             <g
46 |               className="ant-empty-img-default-g"
47 |               transform="translate(149.65 15.383)"
48 |             >
49 |               <ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815"></ellipse>
50 |               <path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z"></path>
51 |             </g>
52 |           </g>
53 |         </svg>
54 |       </div>
55 |     </div>
56 |   )
57 | }
58 | 
```

--------------------------------------------------------------------------------
/packages/next/src/date-picker/index.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import moment from 'moment'
  2 | import { connect, mapProps, mapReadPretty } from '@formily/react'
  3 | import { DatePicker as NextDatePicker } from '@alifd/next'
  4 | import {
  5 |   DatePickerProps as NextDatePickerProps,
  6 |   MonthPickerProps,
  7 |   YearPickerProps,
  8 |   RangePickerProps,
  9 | } from '@alifd/next/lib/date-picker'
 10 | import { PreviewText } from '../preview-text'
 11 | import {
 12 |   formatMomentValue,
 13 |   momentable,
 14 |   mapSize,
 15 |   mapStatus,
 16 | } from '../__builtins__'
 17 | 
 18 | type DatePickerProps<PickerProps> = Exclude<
 19 |   PickerProps,
 20 |   'value' | 'onChange'
 21 | > & {
 22 |   value: string
 23 |   onChange: (value: string | string[]) => void
 24 | }
 25 | 
 26 | type ComposedDatePicker = React.FC<
 27 |   React.PropsWithChildren<NextDatePickerProps>
 28 | > & {
 29 |   RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>
 30 |   MonthPicker?: React.FC<React.PropsWithChildren<MonthPickerProps>>
 31 |   YearPicker?: React.FC<React.PropsWithChildren<YearPickerProps>>
 32 |   WeekPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>
 33 | }
 34 | 
 35 | const mapDateFormat = function (type?: 'month' | 'year' | 'week') {
 36 |   const getDefaultFormat = (props: DatePickerProps<NextDatePickerProps>) => {
 37 |     const _type = props['type'] || type
 38 |     if (_type === 'month') {
 39 |       return 'YYYY-MM'
 40 |     } else if (_type === 'year') {
 41 |       return 'YYYY'
 42 |     } else if (_type === 'week') {
 43 |       return 'YYYY-wo'
 44 |     }
 45 |     return 'YYYY-MM-DD'
 46 |   }
 47 | 
 48 |   return (props: any) => {
 49 |     const dateFormat = props['format'] || getDefaultFormat(props)
 50 | 
 51 |     let valueFormat = dateFormat
 52 |     if (props.showTime) {
 53 |       const timeFormat = props.showTime.format || 'HH:mm:ss'
 54 |       valueFormat = `${valueFormat} ${timeFormat}`
 55 |     }
 56 | 
 57 |     const onChange = props.onChange
 58 |     return {
 59 |       ...props,
 60 |       format: dateFormat,
 61 |       value: momentable(
 62 |         props.value,
 63 |         valueFormat === 'YYYY-wo' ? 'YYYY-w' : valueFormat
 64 |       ),
 65 |       onChange: (value: moment.Moment | moment.Moment[]) => {
 66 |         if (onChange) {
 67 |           onChange(formatMomentValue(value, valueFormat))
 68 |         }
 69 |       },
 70 |     }
 71 |   }
 72 | }
 73 | 
 74 | export const DatePicker: ComposedDatePicker = connect(
 75 |   NextDatePicker,
 76 |   mapProps(mapDateFormat(), mapSize, mapStatus),
 77 |   mapReadPretty(PreviewText.DatePicker)
 78 | )
 79 | 
 80 | DatePicker.RangePicker = connect(
 81 |   NextDatePicker.RangePicker,
 82 |   mapProps(mapDateFormat(), mapSize, mapStatus),
 83 |   mapReadPretty(PreviewText.DateRangePicker)
 84 | )
 85 | 
 86 | DatePicker.YearPicker = connect(
 87 |   NextDatePicker.YearPicker,
 88 |   mapProps(mapDateFormat('year'), mapSize, mapStatus),
 89 |   mapReadPretty(PreviewText.DatePicker)
 90 | )
 91 | 
 92 | DatePicker.MonthPicker = connect(
 93 |   NextDatePicker.MonthPicker,
 94 |   mapProps(mapDateFormat('month'), mapSize, mapStatus),
 95 |   mapReadPretty(PreviewText.DatePicker)
 96 | )
 97 | 
 98 | DatePicker.WeekPicker = connect(
 99 |   NextDatePicker.WeekPicker,
100 |   mapProps(mapDateFormat('week'), mapSize, mapStatus),
101 |   mapReadPretty(PreviewText.DatePicker)
102 | )
103 | 
104 | export default DatePicker
105 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/array-collapse/effects-markup-schema.vue:
--------------------------------------------------------------------------------

```vue
  1 | <template>
  2 |   <FormProvider :form="form">
  3 |     <SchemaField>
  4 |       <SchemaArrayField
  5 |         name="array"
  6 |         :maxItems="3"
  7 |         x-component="ArrayCollapse"
  8 |         x-decorator="FormItem"
  9 |         :x-component-props="{
 10 |           title: '对象数组',
 11 |         }"
 12 |       >
 13 |         <SchemaObjectField
 14 |           x-component="ArrayCollapse.Item"
 15 |           x-decorator="FormItem"
 16 |           :x-component-props="{
 17 |             title: '对象数组',
 18 |           }"
 19 |         >
 20 |           <SchemaVoidField x-component="ArrayCollapse.Index" />
 21 |           <SchemaStringField
 22 |             name="aa"
 23 |             x-decorator="FormItem"
 24 |             title="AA"
 25 |             required
 26 |             description="AA输入123时隐藏BB"
 27 |             x-component="Input"
 28 |           />
 29 |           <SchemaStringField
 30 |             name="bb"
 31 |             x-decorator="FormItem"
 32 |             title="BB"
 33 |             required
 34 |             x-component="Input"
 35 |           />
 36 |           <SchemaStringField
 37 |             name="cc"
 38 |             x-decorator="FormItem"
 39 |             title="CC"
 40 |             required
 41 |             description="CC输入123时隐藏DD"
 42 |             x-component="Input"
 43 |           />
 44 |           <SchemaStringField
 45 |             name="dd"
 46 |             x-decorator="FormItem"
 47 |             title="DD"
 48 |             required
 49 |             x-component="Input"
 50 |           />
 51 |           <SchemaVoidField x-component="ArrayCollapse.Remove" />
 52 |           <SchemaVoidField x-component="ArrayCollapse.MoveUp" />
 53 |           <SchemaVoidField x-component="ArrayCollapse.MoveDown" />
 54 |         </SchemaObjectField>
 55 |         <SchemaVoidField
 56 |           x-component="ArrayCollapse.Addition"
 57 |           title="添加条目"
 58 |         />
 59 |       </SchemaArrayField>
 60 |     </SchemaField>
 61 |     <Submit @submit="log">提交</Submit>
 62 |   </FormProvider>
 63 | </template>
 64 | 
 65 | <script>
 66 | import { createForm, onFieldChange, onFieldReact } from '@formily/core'
 67 | import { FormProvider, createSchemaField } from '@formily/vue'
 68 | import {
 69 |   FormItem,
 70 |   FormButtonGroup,
 71 |   Submit,
 72 |   Input,
 73 |   ArrayCollapse,
 74 | } from '@formily/element'
 75 | import { Button } from 'element-ui'
 76 | 
 77 | const SchemaField = createSchemaField({
 78 |   components: {
 79 |     FormItem,
 80 |     Input,
 81 |     ArrayCollapse,
 82 |   },
 83 | })
 84 | 
 85 | export default {
 86 |   components: {
 87 |     FormProvider,
 88 |     FormButtonGroup,
 89 |     Button,
 90 |     Submit,
 91 |     ...SchemaField,
 92 |   },
 93 | 
 94 |   data() {
 95 |     const form = createForm({
 96 |       effects: () => {
 97 |         //主动联动模式
 98 |         onFieldChange('array.*.aa', ['value'], (field, form) => {
 99 |           form.setFieldState(field.query('.bb'), (state) => {
100 |             state.visible = field.value != '123'
101 |           })
102 |         })
103 |         //被动联动模式
104 |         onFieldReact('array.*.dd', (field) => {
105 |           field.visible = field.query('.cc').get('value') != '123'
106 |         })
107 |       },
108 |     })
109 | 
110 |     return {
111 |       form,
112 |     }
113 |   },
114 |   methods: {
115 |     log(values) {
116 |       console.log(values)
117 |     },
118 |   },
119 | }
120 | </script>
121 | 
122 | <style lang="scss" scoped></style>
123 | 
```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/array-cards/effects-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 |   FormItem,
 13 |   FormButtonGroup,
 14 |   Submit,
 15 |   Input,
 16 |   ArrayCards,
 17 | } from '@formily/element'
 18 | import { Button } from 'element-ui'
 19 | 
 20 | const SchemaField = createSchemaField({
 21 |   components: {
 22 |     FormItem,
 23 |     Input,
 24 |     ArrayCards,
 25 |   },
 26 | })
 27 | 
 28 | export default {
 29 |   components: {
 30 |     FormProvider,
 31 |     FormButtonGroup,
 32 |     Button,
 33 |     Submit,
 34 |     ...SchemaField,
 35 |   },
 36 | 
 37 |   data() {
 38 |     const form = createForm()
 39 |     const schema = {
 40 |       type: 'object',
 41 |       properties: {
 42 |         array: {
 43 |           type: 'array',
 44 |           'x-component': 'ArrayCards',
 45 |           maxItems: 3,
 46 |           title: '对象数组',
 47 |           items: {
 48 |             type: 'object',
 49 |             properties: {
 50 |               index: {
 51 |                 type: 'void',
 52 |                 'x-component': 'ArrayCards.Index',
 53 |               },
 54 |               aa: {
 55 |                 type: 'string',
 56 |                 'x-decorator': 'FormItem',
 57 |                 title: 'AA',
 58 |                 required: true,
 59 |                 'x-component': 'Input',
 60 |                 description: '输入123',
 61 |               },
 62 |               bb: {
 63 |                 type: 'string',
 64 |                 title: 'BB',
 65 |                 required: true,
 66 |                 'x-decorator': 'FormItem',
 67 |                 'x-component': 'Input',
 68 |                 'x-reactions': [
 69 |                   {
 70 |                     dependencies: ['.aa'],
 71 |                     when: "{{$deps[0] != '123'}}",
 72 |                     fulfill: {
 73 |                       schema: {
 74 |                         title: 'BB',
 75 |                         'x-disabled': true,
 76 |                       },
 77 |                     },
 78 |                     otherwise: {
 79 |                       schema: {
 80 |                         title: 'Changed',
 81 |                         'x-disabled': false,
 82 |                       },
 83 |                     },
 84 |                   },
 85 |                 ],
 86 |               },
 87 |               remove: {
 88 |                 type: 'void',
 89 |                 'x-component': 'ArrayCards.Remove',
 90 |               },
 91 |               moveUp: {
 92 |                 type: 'void',
 93 |                 'x-component': 'ArrayCards.MoveUp',
 94 |               },
 95 |               moveDown: {
 96 |                 type: 'void',
 97 |                 'x-component': 'ArrayCards.MoveDown',
 98 |               },
 99 |             },
100 |           },
101 |           properties: {
102 |             addition: {
103 |               type: 'void',
104 |               title: '添加条目',
105 |               'x-component': 'ArrayCards.Addition',
106 |             },
107 |           },
108 |         },
109 |       },
110 |     }
111 | 
112 |     return {
113 |       form,
114 |       schema,
115 |     }
116 |   },
117 |   methods: {
118 |     log(values) {
119 |       console.log(values)
120 |     },
121 |   },
122 | }
123 | </script>
124 | 
125 | <style lang="scss" scoped></style>
126 | 
```

--------------------------------------------------------------------------------
/packages/validator/src/registry.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   FormPath,
  3 |   each,
  4 |   lowerCase,
  5 |   globalThisPolyfill,
  6 |   merge as deepmerge,
  7 |   isFn,
  8 |   isStr,
  9 | } from '@formily/shared'
 10 | import {
 11 |   ValidatorFunctionResponse,
 12 |   ValidatorFunction,
 13 |   IRegistryFormats,
 14 |   IRegistryLocaleMessages,
 15 |   IRegistryLocales,
 16 |   IRegistryRules,
 17 | } from './types'
 18 | 
 19 | const getIn = FormPath.getIn
 20 | 
 21 | const self: any = globalThisPolyfill
 22 | 
 23 | const defaultLanguage = 'en'
 24 | 
 25 | const getBrowserlanguage = () => {
 26 |   /* istanbul ignore next */
 27 |   if (!self.navigator) {
 28 |     return defaultLanguage
 29 |   }
 30 |   return (
 31 |     self.navigator.browserlanguage || self.navigator.language || defaultLanguage
 32 |   )
 33 | }
 34 | 
 35 | const registry = {
 36 |   locales: {
 37 |     messages: {},
 38 |     language: getBrowserlanguage(),
 39 |   },
 40 |   formats: {},
 41 |   rules: {},
 42 |   template: null,
 43 | }
 44 | 
 45 | const getISOCode = (language: string) => {
 46 |   let isoCode = registry.locales.language
 47 |   if (registry.locales.messages[language]) {
 48 |     return language
 49 |   }
 50 |   const lang = lowerCase(language)
 51 |   each(
 52 |     registry.locales.messages,
 53 |     (messages: IRegistryLocaleMessages, key: string) => {
 54 |       const target = lowerCase(key)
 55 |       if (target.indexOf(lang) > -1 || lang.indexOf(target) > -1) {
 56 |         isoCode = key
 57 |         return false
 58 |       }
 59 |     }
 60 |   )
 61 |   return isoCode
 62 | }
 63 | 
 64 | export const getValidateLocaleIOSCode = getISOCode
 65 | 
 66 | export const setValidateLanguage = (lang: string) => {
 67 |   registry.locales.language = lang || defaultLanguage
 68 | }
 69 | 
 70 | export const getValidateLanguage = () => registry.locales.language
 71 | 
 72 | export const getLocaleByPath = (
 73 |   path: string,
 74 |   lang: string = registry.locales.language
 75 | ) => getIn(registry.locales.messages, `${getISOCode(lang)}.${path}`)
 76 | 
 77 | export const getValidateLocale = (path: string) => {
 78 |   const message = getLocaleByPath(path)
 79 |   return (
 80 |     message ||
 81 |     getLocaleByPath('pattern') ||
 82 |     getLocaleByPath('pattern', defaultLanguage)
 83 |   )
 84 | }
 85 | 
 86 | export const getValidateMessageTemplateEngine = () => registry.template
 87 | 
 88 | export const getValidateFormats = (key?: string) =>
 89 |   key ? registry.formats[key] : registry.formats
 90 | 
 91 | export const getValidateRules = <T>(
 92 |   key?: T
 93 | ): T extends string
 94 |   ? ValidatorFunction
 95 |   : { [key: string]: ValidatorFunction } =>
 96 |   key ? registry.rules[key as any] : registry.rules
 97 | 
 98 | export const registerValidateLocale = (locale: IRegistryLocales) => {
 99 |   registry.locales.messages = deepmerge(registry.locales.messages, locale)
100 | }
101 | 
102 | export const registerValidateRules = (rules: IRegistryRules) => {
103 |   each(rules, (rule, key) => {
104 |     if (isFn(rule)) {
105 |       registry.rules[key] = rule
106 |     }
107 |   })
108 | }
109 | 
110 | export const registerValidateFormats = (formats: IRegistryFormats) => {
111 |   each(formats, (pattern, key) => {
112 |     if (isStr(pattern) || pattern instanceof RegExp) {
113 |       registry.formats[key] = new RegExp(pattern)
114 |     }
115 |   })
116 | }
117 | 
118 | export const registerValidateMessageTemplateEngine = (
119 |   template: (message: ValidatorFunctionResponse, context: any) => any
120 | ) => {
121 |   registry.template = template
122 | }
123 | 
```

--------------------------------------------------------------------------------
/packages/core/docs/api/entry/FormValidatorRegistry.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | order: 6
  3 | ---
  4 | 
  5 | # Form Validator Registry
  6 | 
  7 | ## setValidateLanguage
  8 | 
  9 | #### Description
 10 | 
 11 | Set the built-in verification rule language
 12 | 
 13 | #### Signature
 14 | 
 15 | ```ts
 16 | interface setValidateLanguage {
 17 |   (language: string): void
 18 | }
 19 | ```
 20 | 
 21 | #### Example
 22 | 
 23 | ```ts
 24 | import { setValidateLanguage } from '@formily/core'
 25 | 
 26 | setValidateLanguage('en-US')
 27 | 
 28 | setValidateLanguage('zh-CN')
 29 | ```
 30 | 
 31 | ## registerValidateFormats
 32 | 
 33 | #### Description
 34 | 
 35 | Register general regular rules, the current built-in regular library reference: [formats.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/formats.ts)
 36 | 
 37 | #### Signature
 38 | 
 39 | ```ts
 40 | interface registerValidateFormats {
 41 |   (rules: { [key: string]: RegExp }): void
 42 | }
 43 | ```
 44 | 
 45 | #### Example
 46 | 
 47 | ```ts
 48 | import { registerValidateFormats } from '@formily/core'
 49 | 
 50 | registerValidateFormats({
 51 |   integer: /^[+-]?\d+$/,
 52 | })
 53 | ```
 54 | 
 55 | ## registerValidateLocale
 56 | 
 57 | #### Description
 58 | 
 59 | Global registration verification language package, the current built-in language package reference: [locale.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/locale.ts)
 60 | 
 61 | #### Signature
 62 | 
 63 | ```ts
 64 | interface registerValidateLocale {
 65 |   (locales: {
 66 |     [key: string]: {
 67 |       key: string
 68 |     }
 69 |   }): void
 70 | }
 71 | ```
 72 | 
 73 | #### Example
 74 | 
 75 | ```ts
 76 | import { registerValidateLocale } from '@formily/core'
 77 | 
 78 | registerValidateLocale({
 79 |   ja: {
 80 |     required: 'このProjectは mustです',
 81 |   },
 82 | })
 83 | ```
 84 | 
 85 | ## registerValidateMessageTemplateEngine
 86 | 
 87 | #### Description
 88 | 
 89 | Globally register the verification message template engine. When we return the verification message in the validator, we can perform conversion based on the template engine syntax
 90 | 
 91 | #### Signature
 92 | 
 93 | ```ts
 94 | interface registerValidateMessageTemplateEngine {
 95 |   (template: (message: ValidatorFunctionResponse, context: any) => any): void
 96 | }
 97 | ```
 98 | 
 99 | #### Example
100 | 
101 | ```ts
102 | import { registerValidateMessageTemplateEngine } from '@formily/core'
103 | 
104 | registerValidateMessageTemplateEngine((message, context) => {
105 |   return message.replace(/\<\%\s*([\w.]+)\s*\%\>/g, (_, $0) => {
106 |     return FormPath.getIn(context, $0)
107 |   })
108 | })
109 | ```
110 | 
111 | ## registerValidateRules
112 | 
113 | #### Description
114 | 
115 | Register general verification rules, the current built-in rule library reference: [rules.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/rules.ts)
116 | 
117 | #### Signature
118 | 
119 | ```ts
120 | interface registerValidateRules {
121 |   (rules: {
122 |     [key: string]: (
123 |       value: any,
124 |       rule: ValidatorRules,
125 |       ctx: Context
126 |     ) => ValidateResult | Promise<ValidateResult>
127 |   }): void
128 | }
129 | ```
130 | 
131 | #### Example
132 | 
133 | ```ts
134 | import { registerValidateRules } from '@formily/core'
135 | 
136 | registerValidateRules({
137 |   custom(value) {
138 |     return value > 100 ? 'error' : ''
139 |   },
140 | })
141 | ```
142 | 
143 | ## getValidateLocaleIOSCode
144 | 
145 | #### Description
146 | 
147 | Get the built-in ISO Code
148 | 
149 | #### Signature
150 | 
151 | ```ts
152 | interface getValidateLocaleIOSCode {
153 |   (language: string): string | undefined
154 | }
155 | ```
156 | 
157 | #### Example
158 | 
159 | ```ts
160 | import { getValidateLocaleIOSCode } from '@formily/core'
161 | 
162 | getValidateLocaleIOSCode('en')
163 | 
164 | // ==> en_US
165 | ```
166 | 
```

--------------------------------------------------------------------------------
/packages/next/src/date-picker2/index.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import moment from 'moment'
  2 | import { connect, mapProps, mapReadPretty } from '@formily/react'
  3 | import { DatePicker2 as NextDatePicker } from '@alifd/next'
  4 | import {
  5 |   DatePickerProps as NextDatePickerProps,
  6 |   RangePickerProps,
  7 | } from '@alifd/next/lib/date-picker2'
  8 | import { PreviewText } from '../preview-text'
  9 | import {
 10 |   formatMomentValue,
 11 |   momentable,
 12 |   mapSize,
 13 |   mapStatus,
 14 | } from '../__builtins__'
 15 | 
 16 | type DatePickerProps<PickerProps> = Exclude<
 17 |   PickerProps,
 18 |   'value' | 'onChange'
 19 | > & {
 20 |   value: string
 21 |   onChange: (value: string | string[]) => void
 22 | }
 23 | 
 24 | type ComposedDatePicker = React.FC<
 25 |   React.PropsWithChildren<NextDatePickerProps>
 26 | > & {
 27 |   RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>
 28 |   MonthPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>
 29 |   YearPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>
 30 |   WeekPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>
 31 |   QuarterPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>
 32 | }
 33 | 
 34 | const mapDateFormat = function (type?: 'month' | 'year' | 'week' | 'quarter') {
 35 |   const getDefaultFormat = (props: DatePickerProps<NextDatePickerProps>) => {
 36 |     const _type = props['type'] || type
 37 |     if (_type === 'month') {
 38 |       return 'YYYY-MM'
 39 |     } else if (_type === 'quarter') {
 40 |       return 'YYYY-\\QQ'
 41 |     } else if (_type === 'year') {
 42 |       return 'YYYY'
 43 |     } else if (_type === 'week') {
 44 |       return 'YYYY-wo'
 45 |     }
 46 |     return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'
 47 |   }
 48 | 
 49 |   return (props: any) => {
 50 |     const format = props['format'] || getDefaultFormat(props)
 51 |     const onChange = props.onChange
 52 |     return {
 53 |       ...props,
 54 |       format,
 55 |       value: momentable(props.value, format === 'YYYY-wo' ? 'YYYY-w' : format),
 56 |       onChange: (value: moment.Moment | moment.Moment[]) => {
 57 |         if (onChange) {
 58 |           onChange(formatMomentValue(value, format))
 59 |         }
 60 |       },
 61 |     }
 62 |   }
 63 | }
 64 | 
 65 | export const DatePicker2: ComposedDatePicker = connect(
 66 |   NextDatePicker,
 67 |   mapProps(mapDateFormat(), mapSize, mapStatus),
 68 |   mapReadPretty(PreviewText.DatePicker)
 69 | )
 70 | 
 71 | DatePicker2.RangePicker = connect(
 72 |   NextDatePicker.RangePicker,
 73 |   mapProps(mapDateFormat(), mapSize, mapStatus),
 74 |   mapReadPretty(PreviewText.DateRangePicker)
 75 | )
 76 | 
 77 | DatePicker2.YearPicker = connect(
 78 |   NextDatePicker.YearPicker,
 79 |   mapProps(mapDateFormat('year'), mapSize, mapStatus),
 80 |   mapReadPretty(PreviewText.DatePicker)
 81 | )
 82 | 
 83 | DatePicker2.MonthPicker = connect(
 84 |   NextDatePicker.MonthPicker,
 85 |   mapProps(mapDateFormat('month'), mapSize, mapStatus),
 86 |   mapReadPretty(PreviewText.DatePicker)
 87 | )
 88 | 
 89 | DatePicker2.WeekPicker = connect(
 90 |   NextDatePicker.WeekPicker,
 91 |   mapProps(mapDateFormat('week'), mapSize, mapStatus),
 92 |   mapReadPretty(PreviewText.DatePicker)
 93 | )
 94 | 
 95 | DatePicker2.QuarterPicker = connect(
 96 |   NextDatePicker.QuarterPicker,
 97 |   mapProps(mapDateFormat('quarter'), mapSize, mapStatus),
 98 |   mapReadPretty(PreviewText.DatePicker)
 99 | )
100 | 
101 | export default DatePicker2
102 | 
```
Page 10/52FirstPrevNextLast