#
tokens: 49766/50000 58/1152 files (page 5/35)
lines: off (toggle) GitHub
raw markdown copy
This is page 5 of 35. Use http://codebase.md/alibaba/formily?lines=false&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/vue/docs/demos/api/hooks/use-form-effects.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Field
      name="input"
      :decorator="[FormItem]"
      :component="[Input, { placeholder: 'input' }]"
    />
    <Field name="custom" :decorator="[FormItem]" :component="[Custom]" />
  </FormProvider>
</template>

<script>
import { defineComponent, h } from '@vue/composition-api'
import { createForm, onFieldReact } from '@formily/core'
import { FormProvider, Field, useFormEffects } from '@formily/vue'
import { Form, Input } from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'

const Custom = defineComponent({
  setup() {
    useFormEffects(() => {
      onFieldReact('custom.bb', (field) => {
        field.value = field.query('.aa').get('value')
      })
    })
    return () =>
      h('div', {}, [
        h(
          Field,
          {
            props: {
              name: 'aa',
              decorator: [Form.Item],
              component: [Input, { placeholder: 'aa' }],
            },
          },
          {}
        ),
        h(
          Field,
          {
            props: {
              name: 'bb',
              decorator: [Form.Item],
              component: [Input, { placeholder: 'bb' }],
            },
          },
          {}
        ),
      ])
  },
})

export default {
  components: {
    FormProvider,
    Field,
  },
  data() {
    const form = createForm({
      effects() {
        onFieldReact('custom.aa', (field) => {
          field.value = field.query('input').get('value')
        })
      },
    })
    return {
      FormItem: Form.Item,
      Input,
      Custom,
      form,
    }
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/core/src/models/Graph.ts:
--------------------------------------------------------------------------------

```typescript
import { define, batch } from '@formily/reactive'
import { each, FormPath } from '@formily/shared'
import { IFormGraph } from '../types'
import { Form } from './Form'
import {
  isFormState,
  isFieldState,
  isArrayFieldState,
  isObjectFieldState,
} from '../shared/checkers'

export class Graph {
  form: Form

  constructor(form: Form) {
    this.form = form
    define(this, {
      setGraph: batch,
    })
  }

  getGraph = (): IFormGraph => {
    const graph = {}
    graph[''] = this.form.getState()
    each(this.form.fields, (field: any, identifier) => {
      graph[identifier] = field.getState()
    })
    return graph
  }

  setGraph = (graph: IFormGraph) => {
    const form = this.form
    const createField = (identifier: string, state: any) => {
      const address = FormPath.parse(identifier)
      const name = address.segments[address.segments.length - 1]
      const basePath = address.parent()
      if (isFieldState(state)) {
        return this.form.createField({ name, basePath })
      } else if (isArrayFieldState(state)) {
        return this.form.createArrayField({ name, basePath })
      } else if (isObjectFieldState(state)) {
        return this.form.createObjectField({ name, basePath })
      } else {
        return this.form.createVoidField({ name, basePath })
      }
    }
    each(graph, (state, address) => {
      if (isFormState(state)) {
        form.setState(state)
      } else {
        const field = form.fields[address]
        if (field) {
          field.setState(state)
        } else {
          createField(address, state).setState(state)
        }
      }
    })
  }
}

```

--------------------------------------------------------------------------------
/devtools/chrome-extension/src/app/components/filter.ts:
--------------------------------------------------------------------------------

```typescript
// Helper functions for filtering
export const defaultMatcher = (filterText, node) => {
  return node.name.toLowerCase().indexOf(filterText.toLowerCase()) !== -1
}

export const findNode = (node, filter, matcher) => {
  return (
    matcher(filter, node) || // i match
    (node.children && // or i have decendents and one of them match
      node.children.length &&
      !!node.children.find((child) => findNode(child, filter, matcher)))
  )
}

export const filterTree = (node, filter, matcher = defaultMatcher) => {
  // If im an exact match then all my children get to stay
  if (matcher(filter, node) || !node.children) {
    return node
  }
  // If not then only keep the ones that match or have matching descendants
  const filtered = node.children
    .filter((child) => findNode(child, filter, matcher))
    .map((child) => filterTree(child, filter, matcher))
  return Object.assign({}, node, { children: filtered })
}

export const expandFilteredNodes = (node, filter, matcher = defaultMatcher) => {
  let children = node.children
  if (!children || children.length === 0) {
    return Object.assign({}, node, { toggled: false })
  }
  const childrenWithMatches = node.children.filter((child) =>
    findNode(child, filter, matcher)
  )
  const shouldExpand = childrenWithMatches.length > 0
  // If im going to expand, go through all the matches and see if thier children need to expand
  if (shouldExpand) {
    children = childrenWithMatches.map((child) => {
      return expandFilteredNodes(child, filter, matcher)
    })
  }
  return Object.assign({}, node, {
    children: children,
    toggled: shouldExpand,
  })
}

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/shared/connect.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Form layout="vertical">
      <Field
        name="name"
        title="Name"
        required
        :decorator="[FormItem]"
        :component="[Input, { placeholder: 'Please Input' }]"
      />
      <FormConsumer>
        <template #default="{ form }">
          <div style="white-space: pre; margin-bottom: 16px">
            {{ JSON.stringify(form.values, null, 2) }}
          </div>
          <Button
            type="primary"
            @click="
              () => {
                form.submit(log)
              }
            "
          >
            Submit
          </Button>
        </template>
      </FormConsumer>
    </Form>
  </FormProvider>
</template>

<script>
import { Form, Input, Button } from 'ant-design-vue'
import { createForm, setValidateLanguage } from '@formily/core'
import {
  FormProvider,
  FormConsumer,
  Field,
  connect,
  mapProps,
} from '@formily/vue'
import 'ant-design-vue/dist/antd.css'

setValidateLanguage('en')

const FormItem = connect(
  Form.Item,
  mapProps(
    {
      title: 'label',
      description: 'extra',
      required: true,
      validateStatus: true,
    },
    (props, field) => {
      return {
        ...props,
        help: field.selfErrors?.length ? field.selfErrors : undefined,
      }
    }
  )
)

export default {
  components: {
    FormProvider,
    FormConsumer,
    Field,
    Form,
    Button,
  },
  data() {
    const form = createForm({ validateFirst: true })
    return {
      FormItem,
      Input,
      form,
    }
  },
  methods: {
    log(...args) {
      console.log(...args)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/shared/map-props.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Form layout="vertical">
      <Field
        name="name"
        title="Name"
        required
        :decorator="[FormItem]"
        :component="[Input, { placeholder: 'Please Input' }]"
      />
      <FormConsumer>
        <template #default="{ form }">
          <div style="white-space: pre; margin-bottom: 16px">
            {{ JSON.stringify(form.values, null, 2) }}
          </div>
          <Button
            type="primary"
            @click="
              () => {
                form.submit(log)
              }
            "
          >
            Submit
          </Button>
        </template>
      </FormConsumer>
    </Form>
  </FormProvider>
</template>

<script>
import { Form, Input, Button } from 'ant-design-vue'
import { createForm, setValidateLanguage } from '@formily/core'
import {
  FormProvider,
  FormConsumer,
  Field,
  connect,
  mapProps,
} from '@formily/vue'
import 'ant-design-vue/dist/antd.css'

setValidateLanguage('en')

const FormItem = connect(
  Form.Item,
  mapProps(
    {
      title: 'label',
      description: 'extra',
      required: true,
      validateStatus: true,
    },
    (props, field) => {
      return {
        ...props,
        help: field.selfErrors?.length ? field.selfErrors : undefined,
      }
    }
  )
)

export default {
  components: {
    FormProvider,
    FormConsumer,
    Field,
    Form,
    Button,
  },
  data() {
    const form = createForm({ validateFirst: true })
    return {
      FormItem,
      Input,
      form,
    }
  },
  methods: {
    log(...args) {
      console.log(...args)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/element/src/array-table/style.scss:
--------------------------------------------------------------------------------

```scss
@import '../__builtins__/styles/common.scss';

$array-table-prefix-cls: '#{$formily-prefix}-array-table';

.#{$array-table-prefix-cls} {
  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {
    margin-bottom: 0 !important;
  }

  &-status-select-dropdown {
    .#{$namespace}-badge {
      line-height: 1;
    }
  }

  &-pagination {
    display: flex;
    justify-content: center;
    margin-top: 8px;

    .#{$array-table-prefix-cls}-status-select.has-error {
      .#{$namespace}-input__inner {
        border-color: $--color-danger !important;
      }
    }
  }

  .#{$namespace}-table {
    .cell {
      overflow: visible;
    }

    .cell.el-tooltip {
      overflow: hidden;
    }

    &__fixed {
      box-shadow: 10px 0 10px -10px rgb(0 0 0 / 12%);
    }

    &__fixed-right {
      box-shadow: -10px 0 10px -10px rgb(0 0 0 / 12%);
    }
  }

  .#{$formily-prefix}-form-item-help {
    position: absolute;
    font-size: 12px;
    top: 100%;
    background: #fff;
    width: 100%;
    margin-top: 3px;
    padding: 3px;
    z-index: 2;
    border-radius: 3px;
    box-shadow: 0 0 10px #eee;
  }

  .#{$formily-prefix}-array-base-addition {
    margin-top: 8px;
    width: 100%;
    border: $--border-width-base dashed $--border-color-base;

    &:hover {
      background-color: $--color-white;
      border-color: $--border-color-hover;
    }

    &:active,
    &:focus {
      background-color: $--color-white;
      border-color: $--color-primary;
    }
  }

  .#{$formily-prefix}-form-item-feedback-layout-popover {
    margin-bottom: 0;
  }

  &-inner-asterisk {
    color: $--color-danger;
    font-weight: $--font-weight-primary;
  }
}

```

--------------------------------------------------------------------------------
/packages/next/src/space/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react'
import { Box } from '@alifd/next'
import { isNumberLike } from '@formily/shared'
import { toArray, usePrefixCls } from '../__builtins__'
import { useFormLayout } from '../form-layout'
export interface ISpaceProps {
  prefix?: string
  className?: string
  style?: React.CSSProperties
  size?: number | 'small' | 'large' | 'middle'
  direction?: 'horizontal' | 'vertical'
  // No `stretch` since many components do not support that.
  align?: 'start' | 'end' | 'center' | 'baseline'
  wrap?: boolean
}

const spaceSize = {
  small: 8,
  middle: 16,
  large: 24,
}

export const Space: React.FC<React.PropsWithChildren<ISpaceProps>> = ({
  direction = 'horizontal',
  size,
  align = 'start',
  ...props
}) => {
  const layout = useFormLayout()
  const prefix = usePrefixCls('space', props)
  const getDirection = () => {
    if (direction === 'horizontal') {
      return 'row'
    } else {
      return 'column'
    }
  }
  const getAlign = () => {
    if (align === 'start') {
      return 'flex-start'
    } else if (align === 'end') {
      return 'flex-end'
    } else {
      return 'center'
    }
  }
  const _size = size ?? layout?.spaceGap ?? 8
  const _align = getAlign()
  return (
    <Box
      {...props}
      spacing={isNumberLike(_size) ? _size : spaceSize[_size] || 8}
      style={{
        alignItems: _align,
        display: 'inline-flex',
        ...props.style,
      }}
      align={_align}
      direction={getDirection()}
    >
      {toArray(props.children, { keepEmpty: true }).map((child, index) => (
        <div className={`${prefix}-item`} key={index}>
          {child}
        </div>
      ))}
    </Box>
  )
}

export default Space

```

--------------------------------------------------------------------------------
/packages/react/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/react",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "module": "esm",
  "umd:main": "dist/formily.react.umd.production.js",
  "unpkg": "dist/formily.react.umd.production.js",
  "jsdelivr": "dist/formily.react.umd.production.js",
  "jsnext:main": "esm",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "start": "dumi dev",
    "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config",
    "build:docs": "dumi build"
  },
  "peerDependencies": {
    "@types/react": ">=16.8.0",
    "@types/react-dom": ">=16.8.0",
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "react-is": ">=16.8.0"
  },
  "peerDependenciesMeta": {
    "@types/react": {
      "optional": true
    },
    "@types/react-dom": {
      "optional": true
    }
  },
  "devDependencies": {
    "dumi": "^1.1.0-rc.8"
  },
  "dependencies": {
    "@formily/core": "2.3.7",
    "@formily/json-schema": "2.3.7",
    "@formily/reactive": "2.3.7",
    "@formily/reactive-react": "2.3.7",
    "@formily/shared": "2.3.7",
    "@formily/validator": "2.3.7",
    "hoist-non-react-statics": "^3.3.2"
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

--------------------------------------------------------------------------------
/devtools/chrome-extension/src/app/components/SearchBox.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react'
import styled from 'styled-components'

const SerachBox = styled.div`
  display: flex;
  align-items: center;
  height: 100%;
  .input-addon {
    padding: 0 5px;
  }
  .form-control {
    width: 50%;
    border: none;
    background: transparent;
    color: white;
    outline: none;
  }
`

const SearchIcon = () => {
  return (
    <svg
      t="1592193216787"
      className="icon"
      viewBox="0 0 1024 1024"
      version="1.1"
      p-id="3365"
      width="12"
      height="12"
    >
      <defs>
        <style type="text/css"></style>
      </defs>
      <path
        d="M976.738462 892.061538L712.861538 630.153846c53.169231-74.830769 80.738462-169.353846 66.953847-269.784615-23.630769-169.353846-161.476923-303.261538-332.8-319.015385C214.646154 17.723077 17.723077 214.646154 41.353846 448.984615c15.753846 169.353846 149.661538 309.169231 319.015385 332.8 100.430769 13.784615 194.953846-13.784615 269.784615-66.953846l261.907692 261.907693c11.815385 11.815385 29.538462 11.815385 41.353847 0l41.353846-41.353847c11.815385-11.815385 11.815385-31.507692 1.969231-43.323077zM157.538462 411.569231C157.538462 271.753846 271.753846 157.538462 411.569231 157.538462s254.030769 114.215385 254.030769 254.030769S551.384615 665.6 411.569231 665.6 157.538462 553.353846 157.538462 411.569231z"
        p-id="3366"
        fill="#9da5ab"
      ></path>
    </svg>
  )
}

export default ({ onSearch }) => {
  return (
    <SerachBox>
      <div className="input-addon">
        <SearchIcon />
      </div>
      <input
        className="form-control"
        onChange={onSearch}
        placeholder="Search the field..."
        type="text"
      />
    </SerachBox>
  )
}

```

--------------------------------------------------------------------------------
/packages/antd/src/upload/placeholder.ts:
--------------------------------------------------------------------------------

```typescript
export const UPLOAD_PLACEHOLDER = [
  {
    ext: /\.docx/i,
    icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',
  },
  {
    ext: /\.pptx/i,
    icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png',
  },
  {
    ext: /\.jpe?g/i,
    icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.pdf/i,
    icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.png/i,
    icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.eps/i,
    icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png',
  },
  {
    ext: /\.ai/i,
    icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png',
  },
  {
    ext: /\.gif/i,
    icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png',
  },
  {
    ext: /\.svg/i,
    icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png',
  },
  {
    ext: /\.xlsx?/i,
    icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png',
  },
  {
    ext: /\.psd?/i,
    icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png',
  },
  {
    ext: /\.(wav|aif|aiff|au|mp1|mp2|mp3|ra|rm|ram|mid|rmi)/i,
    icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png',
  },
  {
    ext: /\.(avi|wmv|mpg|mpeg|vob|dat|3gp|mp4|mkv|rm|rmvb|mov|flv)/i,
    icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.(zip|rar|arj|z|gz|iso|jar|ace|tar|uue|dmg|pkg|lzh|cab)/i,
    icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png',
  },
  {
    ext: /\.[^.]+/i,
    icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png',
  },
]

```

--------------------------------------------------------------------------------
/packages/next/src/upload/placeholder.ts:
--------------------------------------------------------------------------------

```typescript
export const UPLOAD_PLACEHOLDER = [
  {
    ext: /\.docx/i,
    icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',
  },
  {
    ext: /\.pptx/i,
    icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png',
  },
  {
    ext: /\.jpe?g/i,
    icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.pdf/i,
    icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.png/i,
    icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.eps/i,
    icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png',
  },
  {
    ext: /\.ai/i,
    icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png',
  },
  {
    ext: /\.gif/i,
    icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png',
  },
  {
    ext: /\.svg/i,
    icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png',
  },
  {
    ext: /\.xlsx?/i,
    icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png',
  },
  {
    ext: /\.psd?/i,
    icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png',
  },
  {
    ext: /\.(wav|aif|aiff|au|mp1|mp2|mp3|ra|rm|ram|mid|rmi)/i,
    icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png',
  },
  {
    ext: /\.(avi|wmv|mpg|mpeg|vob|dat|3gp|mp4|mkv|rm|rmvb|mov|flv)/i,
    icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
  },
  {
    ext: /\.(zip|rar|arj|z|gz|iso|jar|ace|tar|uue|dmg|pkg|lzh|cab)/i,
    icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png',
  },
  {
    ext: /\.[^.]+/i,
    icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png',
  },
]

```

--------------------------------------------------------------------------------
/packages/shared/src/isEmpty.ts:
--------------------------------------------------------------------------------

```typescript
import { instOf } from './instanceof'
const has = Object.prototype.hasOwnProperty

const toString = Object.prototype.toString

export const isUndef = (val: any) => val === undefined

export const isValid = (val: any) => val !== undefined && val !== null

export function isEmpty(val: any, strict = false): boolean {
  // Null and Undefined...
  if (val == null) {
    return true
  }

  // Booleans...
  if (typeof val === 'boolean') {
    return false
  }

  // Numbers...
  if (typeof val === 'number') {
    return false
  }

  // Strings...
  if (typeof val === 'string') {
    return val.length === 0
  }

  // Functions...
  if (typeof val === 'function') {
    return val.length === 0
  }

  // Arrays...
  if (Array.isArray(val)) {
    if (val.length === 0) {
      return true
    }
    for (let i = 0; i < val.length; i++) {
      if (strict) {
        if (val[i] !== undefined && val[i] !== null) {
          return false
        }
      } else {
        if (
          val[i] !== undefined &&
          val[i] !== null &&
          val[i] !== '' &&
          val[i] !== 0
        ) {
          return false
        }
      }
    }
    return true
  }

  // Errors...
  if (instOf(val, 'Error')) {
    return val.message === ''
  }

  // Objects...
  if (val.toString === toString) {
    switch (val.toString()) {
      // Maps, Sets, Files and Errors...
      case '[object File]':
      case '[object Map]':
      case '[object Set]': {
        return val.size === 0
      }

      // Plain objects...
      case '[object Object]': {
        for (const key in val) {
          if (has.call(val, key)) {
            return false
          }
        }

        return true
      }
    }
  }

  // Anything else...
  return false
}

```

--------------------------------------------------------------------------------
/devtools/chrome-extension/src/extension/manifest.json:
--------------------------------------------------------------------------------

```json
{
  "version": "0.1.14",
  "name": "Formily DevTools",
  "short_name": "Formily DevTools",
  "description": "Formily DevTools for debugging application's state changes.",
  "homepage_url": "https://github.com/alibaba/formily",
  "manifest_version": 3,
  "action": {
    "default_icon": "img/logo/scalable.png",
    "default_title": "Formily DevTools",
    "default_popup": "popup.html"
  },
  "commands": {
    "devtools-left": {
      "description": "DevTools window to left"
    },
    "devtools-right": {
      "description": "DevTools window to right"
    },
    "devtools-bottom": {
      "description": "DevTools window to bottom"
    },
    "devtools-remote": {
      "description": "Remote DevTools"
    },
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+E"
      }
    }
  },
  "icons": {
    "16": "img/logo/16x16.png",
    "48": "img/logo/48x48.png",
    "128": "img/logo/128x128.png"
  },
  "background": {
    "service_worker": "js/background.bundle.js",
    "type": "module"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "exclude_matches": ["*://www.google.com/*"],
      "js": ["js/content.bundle.js", "js/inject.bundle.js"],
      "run_at": "document_start",
      "all_frames": true
    }
  ],
  "devtools_page": "devtools.html",
  "web_accessible_resources": [
    {
      "resources": ["js/backend.bundle.js"],
      "matches": ["<all_urls>"]
    }
  ],
  "externally_connectable": {
    "ids": ["*"]
  },
  "host_permissions": ["file://*/*", "http://*/*", "https://*/*"],
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
  },
  "update_url": "https://clients2.google.com/service/update2/crx"
}

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/cascader/template.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <Form :form="form">
    <Field
      name="address"
      title="地址选择"
      required
      :decorator="[FormItem]"
      :component="[
        Cascader,
        {
          style: {
            width: '240px',
          },
        },
      ]"
    />

    <Submit @submit="onSubmit">提交</Submit>
  </Form>
</template>

<script>
import { createForm, onFieldReact } from '@formily/core'
import { Field } from '@formily/vue'
import { Form, FormItem, Cascader, Submit } from '@formily/element'
import { action } from '@formily/reactive'
import axios from 'axios'

const transformAddress = (data = {}) => {
  return Object.entries(data).reduce((buf, [key, value]) => {
    if (typeof value === 'string')
      return buf.concat({
        label: value,
        value: key,
      })
    const { name, code, cities, districts } = value
    const _cities = transformAddress(cities)
    const _districts = transformAddress(districts)
    return buf.concat({
      label: name,
      value: code,
      children: _cities.length
        ? _cities
        : _districts.length
        ? _districts
        : undefined,
    })
  }, [])
}

const useAddress = (pattern) => {
  onFieldReact(pattern, (field) => {
    field.loading = true
    axios('//unpkg.com/china-location/dist/location.json')
      .then((res) => res.data)
      .then(
        action.bound((data) => {
          field.dataSource = transformAddress(data)
          field.loading = false
        })
      )
  })
}

const form = createForm({
  effects: () => {
    useAddress('address')
  },
})

export default {
  components: { Form, Field, Submit },
  data() {
    return {
      FormItem,
      Cascader,
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/next/src/array-items/main.scss:
--------------------------------------------------------------------------------

```scss
@import '~@alifd/next/lib/core/index-noreset.scss';

$array-items-prefix-cls: '#{$css-prefix}formily-array-items';

.#{$array-items-prefix-cls} {
  .#{$css-prefix}form-item {
    margin-bottom: 0;
  }
}

// fix https://github.com/alibaba/formily/issues/2891
.#{$array-items-prefix-cls}-item {
  z-index: 100000;
}

.#{$array-items-prefix-cls}-sort-handler {
  cursor: move;
  color: #888 !important;
}

.#{$array-items-prefix-cls}-item-inner {
  margin-bottom: 10px;
  visibility: visible;
}

.#{$array-items-prefix-cls}-card {
  display: flex;
  border: 1px solid #eee;
  margin-bottom: 10px;
  padding: 3px 6px;
  background: #fff;
  justify-content: space-between;
  align-items: center;

  transition: all 0.35s;

  .#{$css-prefix}formily-item:not(.#{$css-prefix}formily-item-feedback-layout-popover) {
    margin-bottom: 0 !important;
    position: relative;

    .#{$css-prefix}formily-item-help {
      position: absolute;
      font-size: 12px;
      top: 100%;
      background: #fff;
      width: 100%;
      margin-top: 3px;
      padding: 3px;
      z-index: 1;
      border-radius: 3px;
      box-shadow: 0 0 10px #eee;
    }
  }
}

.#{$array-items-prefix-cls}-divide {
  display: flex;
  border-bottom: 1px solid #eee;
  margin-bottom: 10px;
  padding: 10px 0;
  background: #fff;
  justify-content: space-between;
  align-items: center;

  .#{$css-prefix}formily-item:not(.#{$css-prefix}formily-item-feedback-layout-popover) {
    margin-bottom: 0 !important;
    position: relative;

    .#{$css-prefix}formily-item-help {
      position: absolute;
      font-size: 12px;
      top: 100%;
      background: #fff;
      width: 100%;
      margin-top: 3px;
      padding: 3px;
      z-index: 1;
      border-radius: 3px;
      box-shadow: 0 0 10px #eee;
    }
  }
}

```

--------------------------------------------------------------------------------
/packages/element/src/array-items/style.scss:
--------------------------------------------------------------------------------

```scss
@import '../__builtins__/styles/common.scss';

$array-items-prefix-cls: '#{$formily-prefix}-array-items';

.#{$array-items-prefix-cls}-item-inner {
  visibility: visible;
}

.#{$array-items-prefix-cls} {
  .#{$formily-prefix}-array-base-addition {
    width: 100%;
    border: $--border-width-base dashed $--border-color-base;

    &:hover {
      background-color: $--color-white;
      border-color: $--border-color-hover;
    }

    &:active,
    &:focus {
      background-color: $--color-white;
      border-color: $--color-primary;
    }
  }
}

.#{$array-items-prefix-cls}-card {
  display: flex;
  border: 1px solid $--card-border-color;
  margin-bottom: 10px;
  padding: 3px 6px;
  background: $--color-white;
  justify-content: space-between;

  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {
    margin-bottom: 0 !important;

    .#{$formily-prefix}-form-item-help {
      position: absolute;
      font-size: 12px;
      top: 100%;
      background: $--color-white;
      width: 100%;
      margin-top: 3px;
      padding: 3px;
      z-index: 1;
      border-radius: 3px;
      box-shadow: 0 0 10px $--border-color-base;
    }
  }
}

.#{$array-items-prefix-cls}-divide {
  display: flex;
  border-bottom: 1px solid $--card-border-color;
  padding: 10px 0;
  justify-content: space-between;

  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {
    margin-bottom: 0 !important;

    .#{$formily-prefix}-form-item-help {
      position: absolute;
      font-size: 12px;
      top: 100%;
      background: $--color-white;
      width: 100%;
      margin-top: 3px;
      padding: 3px;
      z-index: 1;
      border-radius: 3px;
      box-shadow: 0 0 10px $--card-border-color;
    }
  }
}

```

--------------------------------------------------------------------------------
/devtools/chrome-extension/assets/img/loading.svg:
--------------------------------------------------------------------------------

```
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
<svg width="45" height="45" viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
    <g fill="none" fill-rule="evenodd" transform="translate(1 1)" stroke-width="2">
        <circle cx="22" cy="22" r="6" stroke-opacity="0">
            <animate attributeName="r"
                 begin="1.5s" dur="3s"
                 values="6;22"
                 calcMode="linear"
                 repeatCount="indefinite" />
            <animate attributeName="stroke-opacity"
                 begin="1.5s" dur="3s"
                 values="1;0" calcMode="linear"
                 repeatCount="indefinite" />
            <animate attributeName="stroke-width"
                 begin="1.5s" dur="3s"
                 values="2;0" calcMode="linear"
                 repeatCount="indefinite" />
        </circle>
        <circle cx="22" cy="22" r="6" stroke-opacity="0">
            <animate attributeName="r"
                 begin="3s" dur="3s"
                 values="6;22"
                 calcMode="linear"
                 repeatCount="indefinite" />
            <animate attributeName="stroke-opacity"
                 begin="3s" dur="3s"
                 values="1;0" calcMode="linear"
                 repeatCount="indefinite" />
            <animate attributeName="stroke-width"
                 begin="3s" dur="3s"
                 values="2;0" calcMode="linear"
                 repeatCount="indefinite" />
        </circle>
        <circle cx="22" cy="22" r="8">
            <animate attributeName="r"
                 begin="0s" dur="1.5s"
                 values="6;1;2;3;4;5;6"
                 calcMode="linear"
                 repeatCount="indefinite" />
        </circle>
    </g>
</svg>
```

--------------------------------------------------------------------------------
/devtools/chrome-extension/config/webpack.base.ts:
--------------------------------------------------------------------------------

```typescript
import path from 'path'
import fs from 'fs-extra'

const getEntry = (src) => {
  return [path.resolve(__dirname, '../src/extension/', src)]
}

// 先确保删除package目录,再创建新的
const packageDir = path.resolve(__dirname, '../package')
if (fs.existsSync(packageDir)) {
  fs.removeSync(packageDir)
}
fs.ensureDirSync(packageDir)

fs.copy(path.resolve(__dirname, '../assets'), packageDir)

fs.copy(
  path.resolve(__dirname, '../src/extension/manifest.json'),
  path.resolve(__dirname, '../package/manifest.json')
)

export default {
  mode: 'development',
  devtool: 'inline-source-map', // 嵌入到源文件中
  entry: {
    popup: getEntry('./popup.tsx'),
    devtools: getEntry('./devtools.tsx'),
    devpanel: getEntry('./devpanel.tsx'),
    content: getEntry('./content.ts'),
    backend: getEntry('./backend.ts'),
    demo: getEntry('../app/demo.tsx'),
    inject: getEntry('./inject.ts'),
    background: getEntry('./background.ts'),
  },
  output: {
    path: path.resolve(__dirname, '../package'),
    filename: 'js/[name].bundle.js',
  },
  resolve: {
    modules: ['node_modules'],
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: require.resolve('ts-loader'),
            options: {
              transpileOnly: true,
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: require.resolve('style-loader'),
            options: {
              singleton: true,
            },
          },
          require.resolve('css-loader'),
        ],
      },
      {
        test: /\.html?$/,
        loader: require.resolve('file-loader'),
        options: {
          name: '[name].[ext]',
        },
      },
    ],
  },
}

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaArrayField
        name="string_array"
        x-decorator="FormItem"
        title="字符串数组"
        :maxItems="3"
        x-component="ArrayTabs"
      >
        <SchemaStringField
          x-decorator="FormItem"
          required
          x-component="Input"
        />
      </SchemaArrayField>
      <SchemaArrayField
        name="array"
        x-decorator="FormItem"
        title="对象数组"
        :maxItems="3"
        x-component="ArrayTabs"
      >
        <SchemaObjectField>
          <SchemaStringField
            x-decorator="FormItem"
            title="AAA"
            name="aaa"
            required
            x-component="Input"
          />
          <SchemaStringField
            x-decorator="FormItem"
            title="BBB"
            name="bbb"
            required
            x-component="Input"
          />
        </SchemaObjectField>
      </SchemaArrayField>
    </SchemaField>
    <FormButtonGroup>
      <Submit @submit="log">提交</Submit>
    </FormButtonGroup>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import {
  FormItem,
  FormButtonGroup,
  Submit,
  Input,
  Select,
  ArrayTabs,
} from '@formily/element'
import { Button } from 'element-ui'

const SchemaField = createSchemaField({
  components: {
    FormItem,
    Input,
    Select,
    ArrayTabs,
  },
})

export default {
  components: {
    FormProvider,
    FormButtonGroup,
    Button,
    Submit,
    ...SchemaField,
  },

  data() {
    const form = createForm()

    return {
      form,
    }
  },
  methods: {
    log(values) {
      console.log(values)
    },
  },
}
</script>

<style lang="scss" scoped></style>

```

--------------------------------------------------------------------------------
/packages/next/src/form/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { useMemo } from 'react'
import { FormProvider, JSXComponent, useParentForm } from '@formily/react'
import { FormLayout, IFormLayoutProps } from '../form-layout'
import { ConfigProvider } from '@alifd/next'
import {
  getValidateLocaleIOSCode,
  setValidateLanguage,
  Form as FormType,
  ObjectField,
  IFormFeedback,
} from '@formily/core'
import { PreviewText } from '../preview-text'
export interface FormProps extends IFormLayoutProps {
  form?: FormType
  component?: JSXComponent
  onAutoSubmit?: (values: any) => any
  onAutoSubmitFailed?: (feedbacks: IFormFeedback[]) => void
  previewTextPlaceholder?: React.ReactNode
}

export const Form: React.FC<React.PropsWithChildren<FormProps>> = ({
  form,
  component = 'form',
  onAutoSubmit,
  onAutoSubmitFailed,
  previewTextPlaceholder,
  ...props
}) => {
  const top = useParentForm()
  const lang =
    (ConfigProvider as any).getContext()?.locale?.momentLocale ?? 'zh-CN'
  useMemo(() => {
    const validateLanguage = getValidateLocaleIOSCode(lang)
    setValidateLanguage(validateLanguage)
  }, [lang])

  const renderContent = (form: FormType | ObjectField) => (
    <PreviewText.Placeholder value={previewTextPlaceholder}>
      <FormLayout {...props}>
        {React.createElement(
          component,
          {
            onSubmit(e: React.FormEvent) {
              e?.stopPropagation?.()
              e?.preventDefault?.()
              form.submit(onAutoSubmit).catch(onAutoSubmitFailed)
            },
          },
          props.children
        )}
      </FormLayout>
    </PreviewText.Placeholder>
  )

  if (form)
    return <FormProvider form={form}>{renderContent(form)}</FormProvider>
  if (!top) throw new Error('must pass form instance by createForm')
  return renderContent(top)
}

export default Form

```

--------------------------------------------------------------------------------
/packages/next/src/array-cards/main.scss:
--------------------------------------------------------------------------------

```scss
@import '~@alifd/next/lib/core/index-noreset.scss';

$array-cards-prefix-cls: '#{$css-prefix}formily-array-cards';

.#{$css-prefix}empty {
  display: flex;
  justify-content: center;
  align-items: center;

  &-image {
    display: flex;
    justify-content: center;
    align-items: center;
    transform: scale(0.8);

    .ant-empty-img-default-ellipse {
      fill-opacity: 0.8;
      fill: #f5f5f5;
    }

    .ant-empty-img-default-path-1 {
      fill: #aeb8c2;
    }

    .ant-empty-img-default-path-2 {
      fill: url(#linearGradient-1);
    }

    .ant-empty-img-default-path-3 {
      fill: #f5f5f7;
    }

    .ant-empty-img-default-path-4,
    .ant-empty-img-default-path-5 {
      fill: #dce0e6;
    }

    .ant-empty-img-default-g {
      fill: #fff;
    }

    .ant-empty-img-simple-ellipse {
      fill: #f5f5f5;
    }

    .ant-empty-img-simple-g {
      stroke: #d9d9d9;
    }

    .ant-empty-img-simple-path {
      fill: #fafafa;
    }

    .ant-empty-rtl {
      direction: rtl;
    }
  }
}

.#{$array-cards-prefix-cls}-remove {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-cards-prefix-cls}-addition {
  transition: all 0.25s ease-in-out;
}

.#{$array-cards-prefix-cls}-move-down {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-cards-prefix-cls}-move-up {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-cards-prefix-cls}-item {
  margin-bottom: 10px !important;
}

.next-card-extra {
  svg {
    margin-right: 6px;
    &:last-of-type {
      margin-right: 0;
    }
  }
}

```

--------------------------------------------------------------------------------
/packages/element/src/form-button-group/index.ts:
--------------------------------------------------------------------------------

```typescript
import { h } from '@formily/vue'
import { defineComponent } from 'vue-demi'
import { FormBaseItem } from '../form-item'
import { Space, SpaceProps } from '../space'
import { stylePrefix } from '../__builtins__/configs'

export type FormButtonGroupProps = Omit<SpaceProps, 'align' | 'size'> & {
  align?: 'left' | 'right' | 'center'
  gutter?: number
  className?: string
  alignFormItem: boolean
}

export const FormButtonGroup = defineComponent<FormButtonGroupProps>({
  name: 'FFormButtonGroup',
  props: {
    align: {
      type: String,
      default: 'left',
    },
    gutter: {
      type: Number,
      default: 8,
    },
    alignFormItem: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { slots, attrs }) {
    const prefixCls = `${stylePrefix}-form-button-group`
    return () => {
      if (props.alignFormItem) {
        return h(
          FormBaseItem,
          {
            style: {
              margin: 0,
              padding: 0,
              width: '100%',
            },
            attrs: {
              colon: false,
              label: ' ',
              ...attrs,
            },
          },
          {
            default: () => h(Space, { props: { size: props.gutter } }, slots),
          }
        )
      } else {
        return h(
          Space,
          {
            class: [prefixCls],
            style: {
              justifyContent:
                props.align === 'left'
                  ? 'flex-start'
                  : props.align === 'right'
                  ? 'flex-end'
                  : 'center',
              display: 'flex',
            },
            props: {
              ...attrs,
              size: props.gutter,
            },
            attrs,
          },
          slots
        )
      }
    }
  },
})

export default FormButtonGroup

```

--------------------------------------------------------------------------------
/packages/next/src/array-collapse/main.scss:
--------------------------------------------------------------------------------

```scss
@import '~@alifd/next/lib/core/index-noreset.scss';

$array-collapse-prefix-cls: '#{$css-prefix}formily-array-collapse';

.#{$css-prefix}empty {
  display: flex;
  justify-content: center;
  align-items: center;

  &-image {
    display: flex;
    justify-content: center;
    align-items: center;
    transform: scale(0.8);

    .ant-empty-img-default-ellipse {
      fill-opacity: 0.8;
      fill: #f5f5f5;
    }

    .ant-empty-img-default-path-1 {
      fill: #aeb8c2;
    }

    .ant-empty-img-default-path-2 {
      fill: url(#linearGradient-1);
    }

    .ant-empty-img-default-path-3 {
      fill: #f5f5f7;
    }

    .ant-empty-img-default-path-4,
    .ant-empty-img-default-path-5 {
      fill: #dce0e6;
    }

    .ant-empty-img-default-g {
      fill: #fff;
    }

    .ant-empty-img-simple-ellipse {
      fill: #f5f5f5;
    }

    .ant-empty-img-simple-g {
      stroke: #d9d9d9;
    }

    .ant-empty-img-simple-path {
      fill: #fafafa;
    }

    .ant-empty-rtl {
      direction: rtl;
    }
  }
}

.#{$array-collapse-prefix-cls}-remove {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-collapse-prefix-cls}-addition {
  transition: all 0.25s ease-in-out;
}

.#{$array-collapse-prefix-cls}-move-down {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-collapse-prefix-cls}-move-up {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;
  margin-left: 6px;

  &:hover {
    color: $color-text1-1;
  }
}

.#{$array-collapse-prefix-cls}-item {
  margin-bottom: 10px !important;
  .#{$array-collapse-prefix-cls}-item-title {
    display: flex;
    justify-content: space-between;
  }
}

```

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

```vue
<template>
  <Button @click="handleOpen">点击打开表单</Button>
</template>

<script>
import { FormDrawer, FormLayout, FormItem, Input } from '@formily/element'
import { Button } from 'element-ui'
import { createSchemaField } from '@formily/vue'
const { SchemaField } = createSchemaField({
  components: {
    FormItem,
    Input,
  },
})

// 抽屉表单组件
const DrawerForm = {
  data() {
    const schema = {
      type: 'object',
      properties: {
        aaa: {
          type: 'string',
          title: '输入框1',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        bbb: {
          type: 'string',
          title: '输入框2',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ccc: {
          type: 'string',
          title: '输入框3',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ddd: {
          type: 'string',
          title: '输入框4',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
      },
    }
    return {
      schema,
    }
  },
  render(h) {
    return (
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField schema={this.schema} />
        <FormDrawer.Footer>
          <span style={{ marginLeft: '4px' }}>扩展文案</span>
        </FormDrawer.Footer>
      </FormLayout>
    )
  },
}

export default {
  components: { Button },
  data() {
    return {}
  },
  methods: {
    handleOpen() {
      FormDrawer('抽屉表单', DrawerForm)
        .open({
          initialValues: {
            aaa: '123',
          },
        })
        .then((values) => {
          console.log('values', values)
        })
        .catch((e) => {
          console.log(e)
        })
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/form-dialog/template.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <Button @click="handleOpen">点击打开表单</Button>
</template>

<script>
import { FormDialog, FormLayout, FormItem, Input } from '@formily/element'
import { Button } from 'element-ui'
import { Field } from '@formily/vue'

export default {
  components: { Button },
  data() {
    return {}
  },
  methods: {
    handleOpen() {
      FormDialog('弹框表单', () => (
        <FormLayout labelCol={6} wrapperCol={10}>
          <Field
            name="aaa"
            required
            title="输入框1"
            decorator={[FormItem]}
            component={[Input]}
          />
          <Field
            name="bbb"
            required
            title="输入框2"
            decorator={[FormItem]}
            component={[Input]}
          />
          <Field
            name="ccc"
            required
            title="输入框3"
            decorator={[FormItem]}
            component={[Input]}
          />
          <Field
            name="ddd"
            required
            title="输入框4"
            decorator={[FormItem]}
            component={[Input]}
          />
          <FormDialog.Footer>
            <span style={{ marginLeft: '4px' }}>扩展文案</span>
          </FormDialog.Footer>
        </FormLayout>
      ))
        .forOpen((payload, next) => {
          setTimeout(() => {
            next({
              initialValues: {
                aaa: '123',
              },
            })
          }, 1000)
        })
        .forConfirm((payload, next) => {
          setTimeout(() => {
            console.log(payload)
            next(payload)
          }, 1000)
        })
        .forCancel((payload, next) => {
          setTimeout(() => {
            console.log(payload)
            next(payload)
          }, 1000)
        })
        .open()
        .then(console.log)
        .catch(console.error)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/element/src/__builtins__/shared/transform-component.ts:
--------------------------------------------------------------------------------

```typescript
import type { Component } from 'vue'
import { merge } from '@formily/shared'
import { h } from '@formily/vue'
import { isVue2, defineComponent } from 'vue-demi'

type ListenersTransformRules = Record<string, string>
const noop = () => {}

export const transformComponent = <T extends Record<string, any>>(
  tag: any,
  transformRules?: ListenersTransformRules,
  defaultProps?: Partial<T>
): Component<T> | any => {
  if (isVue2) {
    return defineComponent({
      setup(props, { attrs, slots, listeners }) {
        return () => {
          const data = {
            attrs: {
              ...attrs,
            },
            on: {
              ...listeners,
            },
          }

          if (transformRules) {
            const transformListeners = transformRules
            Object.keys(transformListeners).forEach((extract) => {
              if (data.on !== undefined) {
                data.on[transformListeners[extract]] = listeners[extract] || noop
              }
            })
          }
          if (defaultProps) {
            data.attrs = merge(defaultProps, data.attrs)
          }

          return h(tag, data, slots)
        }
      },
    })
  } else {
    return defineComponent({
      setup(props, { attrs, slots }) {
        return () => {
          let data = {
            ...attrs,
          }
          if (transformRules) {
            const listeners = transformRules
            Object.keys(listeners).forEach((extract) => {
              const event = listeners[extract]
              data[`on${event[0].toUpperCase()}${event.slice(1)}`] =
                attrs[`on${extract[0].toUpperCase()}${extract.slice(1)}`] || noop
            })
          }
          if (defaultProps) {
            data = merge(defaultProps, data)
          }
          return h(tag, data, slots)
        }
      },
    })
  }
}

```

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

```typescript
import moment from 'moment'
import { connect, mapProps, mapReadPretty } from '@formily/react'
import { DatePicker as AntdDatePicker } from 'antd'
import {
  DatePickerProps as AntdDatePickerProps,
  RangePickerProps,
} from 'antd/lib/date-picker'
import { PreviewText } from '../preview-text'
import { formatMomentValue, momentable } from '../__builtins__'

type DatePickerProps<PickerProps> = Exclude<
  PickerProps,
  'value' | 'onChange'
> & {
  value: string
  onChange: (value: string | string[]) => void
}

type ComposedDatePicker = React.FC<
  React.PropsWithChildren<AntdDatePickerProps>
> & {
  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>
}

const mapDateFormat = function () {
  const getDefaultFormat = (props: DatePickerProps<AntdDatePickerProps>) => {
    if (props['picker'] === 'month') {
      return 'YYYY-MM'
    } else if (props['picker'] === 'quarter') {
      return 'YYYY-\\QQ'
    } else if (props['picker'] === 'year') {
      return 'YYYY'
    } else if (props['picker'] === 'week') {
      return 'gggg-wo'
    }
    return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'
  }
  return (props: any) => {
    const format = props['format'] || getDefaultFormat(props)
    const onChange = props.onChange
    return {
      ...props,
      format: format,
      value: momentable(props.value, format === 'gggg-wo' ? 'gggg-ww' : format),
      onChange: (value: moment.Moment | moment.Moment[]) => {
        if (onChange) {
          onChange(formatMomentValue(value, format))
        }
      },
    }
  }
}

export const DatePicker: ComposedDatePicker = connect(
  AntdDatePicker,
  mapProps(mapDateFormat()),
  mapReadPretty(PreviewText.DatePicker)
)

DatePicker.RangePicker = connect(
  AntdDatePicker.RangePicker,
  mapProps(mapDateFormat()),
  mapReadPretty(PreviewText.DateRangePicker)
)

export default DatePicker

```

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

```vue
<template>
  <Button @click="handleOpen">点击打开表单</Button>
</template>

<script>
import { FormDrawer, FormLayout, FormItem, Input } from '@formily/element'
import { Button } from 'element-ui'
import { createSchemaField } from '@formily/vue'

const { SchemaField } = createSchemaField({
  components: {
    FormItem,
    Input,
  },
})

// 抽屉表单组件
const DrawerForm = {
  props: ['form'],
  data() {
    const schema = {
      type: 'object',
      properties: {
        aaa: {
          type: 'string',
          title: '输入框1',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        bbb: {
          type: 'string',
          title: '输入框2',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ccc: {
          type: 'string',
          title: '输入框3',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ddd: {
          type: 'string',
          title: '输入框4',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
      },
    }
    return {
      schema,
    }
  },
  render() {
    return (
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField schema={this.schema} />
        <FormDrawer.Footer>
          <span style={{ marginLeft: '4px' }}>扩展文案</span>
        </FormDrawer.Footer>
      </FormLayout>
    )
  },
}

export default {
  components: { Button },
  data() {
    return {}
  },
  methods: {
    handleOpen() {
      FormDrawer('抽屉表单', DrawerForm)
        .forOpen((props, next) => {
          setTimeout(() => {
            next()
          }, 1000)
        })
        .open({
          initialValues: {
            aaa: '123',
          },
        })
        .then(console.log)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/react/docs/api/shared/connect.md:
--------------------------------------------------------------------------------

```markdown
# connect

## Description

Mainly used for non-intrusive access to third-party component libraries Formily

## Signature

```ts
interface IComponentMapper<T extends React.FC> {
  (target: T): React.FC
}
interface connect<T extends React.FC> {
  (target: T, ...args: IComponentMapper<T>[]): React.FC
}
```

The first parameter passed in is the component to be connected, the following parameters are component mappers, each mapper is a function, usually we will use the built-in [mapProps](/api/shared/map- props) and [mapReadPretty](/api/shared/map-read-pretty) mapper

## Example

```tsx
import React, { useMemo } from 'react'
import { createForm } from '@formily/core'
import {
  FormProvider,
  FormConsumer,
  Field,
  connect,
  mapProps,
} from '@formily/react'
import { Input, Form, Button } from 'antd'

// FormItem UI component
const FormItem = connect(
  Form.Item,
  mapProps(
    {
      title: 'label',
      description: 'extra',
      required: true,
      validateStatus: true,
    },
    (props, field) => {
      return {
        ...props,
        help: field.selfErrors?.length ? field.selfErrors : undefined,
      }
    }
  )
)

export default () => {
  const form = useMemo(() => createForm({ validateFirst: true }))
  return (
    <FormProvider form={form}>
      <Form layout="vertical">
        <Field
          name="name"
          title="Name"
          required
          decorator={[FormItem]}
          component={[Input, { placeholder: 'Please Input' }]}
        />
        <code>
          <pre>
            <FormConsumer>
              {(form) => JSON.stringify(form.values, null, 2)}
            </FormConsumer>
          </pre>
        </code>
        <Button
          type="primary"
          onClick={() => {
            form.submit(console.log)
          }}
        >
          Submit
        </Button>
      </Form>
    </FormProvider>
  )
}
```

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaVoidField
        x-component="FormGrid"
        :x-component-props="{
          maxColumns: 3,
          minColumns: 2,
        }"
      >
        <SchemaStringField
          name="aaa"
          title="aaa"
          x-decorator="FormItem"
          :x-decorator-props="{ gridSpan: 2 }"
          x-component="Input"
        />
        <SchemaStringField
          name="bbb"
          title="bbb"
          x-decorator="FormItem"
          x-component="Input"
        />
        <SchemaStringField
          name="ccc"
          title="ccc"
          x-decorator="FormItem"
          x-component="Input"
        />
        <SchemaStringField
          name="ddd"
          title="ddd"
          x-decorator="FormItem"
          x-component="Input"
        />
        <SchemaStringField
          name="eee"
          title="eee"
          x-decorator="FormItem"
          x-component="Input"
        />
        <SchemaStringField
          name="fff"
          title="fff"
          x-decorator="FormItem"
          x-component="Input"
        />
        <SchemaStringField
          name="ggg"
          title="ggg"
          x-decorator="FormItem"
          x-component="Input"
        />
      </SchemaVoidField>
    </SchemaField>
    <Submit @submit="onSubmit">提交</Submit>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField, FormProvider } from '@formily/vue'
import { FormItem, Input, Submit, FormGrid } from '@formily/element'

const form = createForm()
const fields = createSchemaField({
  components: {
    FormItem,
    Input,
    FormGrid,
  },
})

export default {
  components: { FormProvider, ...fields, Submit },
  data() {
    return {
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/react/docs/api/components/RecordsScope.md:
--------------------------------------------------------------------------------

```markdown
---
order: 10
---

# RecordsScope

## Description

Standard scoped injection component for injecting the following built-in variables:

- `$records` current record list data

## Signature

```ts
interface IRecordsScopeProps {
  getRecords(): any[]
}

type RecordsScope = React.FC<React.PropsWithChildren<IRecordsScopeProps>>
```

## Usage

Any auto-incrementing list extension component should use RecordsScope internally to pass record scope variables. Components that have implemented this convention include:
All components of the ArrayX family in @formily/antd and @formily/next

## Custom component extension use case

```tsx
import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField, RecordsScope } from '@formily/react'
import { Input } from 'antd'

const form = createForm()

const MyCustomComponent = (props) => {
  return (
    <RecordsScope getRecords={() => props.records}>
      {props.children}
    </RecordsScope>
  )
}

const SchemaField = createSchemaField({
  components: {
    Input,
    MyCustomComponent,
  },
})

export default () => (
  <FormProvider form={form}>
    <SchemaField
      schema={{
        type: 'object',
        properties: {
          records: {
            type: 'void',
            'x-component': 'MyCustomComponent',
            'x-component-props': {
              records: [
                {
                  name: 'Name',
                  code: 'Code',
                },
              ],
            },
            properties: {
              input: {
                type: 'string',
                'x-component': 'Input',
                'x-value':
                  '{{`' +
                  '${$records[0].name} ' +
                  '${$records[0].code}' +
                  '`}}',
              },
            },
          },
        },
      }}
    ></SchemaField>
  </FormProvider>
)
```

```

--------------------------------------------------------------------------------
/packages/element/src/submit/index.ts:
--------------------------------------------------------------------------------

```typescript
import { IFormFeedback } from '@formily/core'
import { observer } from '@formily/reactive-vue'
import { h, useParentForm } from '@formily/vue'
import { defineComponent } from 'vue-demi'

import type { Button as ElButtonProps } from 'element-ui'
import { Button as ElButton } from 'element-ui'

export interface ISubmitProps extends ElButtonProps {
  onClick?: (e: MouseEvent) => any
  onSubmit?: (values: any) => any
  onSubmitSuccess?: (payload: any) => void
  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void
}

export const Submit = observer(
  defineComponent<ISubmitProps>({
    name: 'FSubmit',
    props: ['onClick', 'onSubmit', 'onSubmitSuccess', 'onSubmitFailed'],
    setup(props, { attrs, slots, listeners }) {
      const formRef = useParentForm()

      return () => {
        const {
          onClick = listeners?.click,
          onSubmit = listeners?.submit,
          onSubmitSuccess = listeners?.submitSuccess,
          onSubmitFailed = listeners?.submitFailed,
        } = props

        const form = formRef?.value
        return h(
          ElButton,
          {
            attrs: {
              nativeType: listeners?.submit ? 'button' : 'submit',
              type: 'primary',
              ...attrs,
              loading:
                attrs.loading !== undefined ? attrs.loading : form?.submitting,
            },
            on: {
              ...listeners,
              click: (e: any) => {
                if (onClick) {
                  if (onClick(e) === false) return
                }
                if (onSubmit) {
                  form
                    ?.submit(onSubmit as (e: any) => void)
                    .then(onSubmitSuccess as (e: any) => void)
                    .catch(onSubmitFailed as (e: any) => void)
                }
              },
            },
          },
          slots
        )
      }
    },
  })
)

export default Submit

```

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

```vue
<template>
  <Form :form="form">
    <SchemaField>
      <SchemaStringField
        name="address"
        title="地址选择"
        required
        x-decorator="FormItem"
        x-component="Cascader"
        :x-component-props="{
          style: {
            width: '240px',
          },
        }"
      />
    </SchemaField>

    <Submit @submit="onSubmit">提交</Submit>
  </Form>
</template>

<script>
import { createForm, onFieldReact } from '@formily/core'
import { createSchemaField } from '@formily/vue'
import { Form, FormItem, Cascader, Submit } from '@formily/element'
import { action } from '@formily/reactive'
import axios from 'axios'

const transformAddress = (data = {}) => {
  return Object.entries(data).reduce((buf, [key, value]) => {
    if (typeof value === 'string')
      return buf.concat({
        label: value,
        value: key,
      })
    const { name, code, cities, districts } = value
    const _cities = transformAddress(cities)
    const _districts = transformAddress(districts)
    return buf.concat({
      label: name,
      value: code,
      children: _cities.length
        ? _cities
        : _districts.length
        ? _districts
        : undefined,
    })
  }, [])
}

const useAddress = (pattern) => {
  onFieldReact(pattern, (field) => {
    field.loading = true
    axios('//unpkg.com/china-location/dist/location.json')
      .then((res) => res.data)
      .then(
        action.bound((data) => {
          field.dataSource = transformAddress(data)
          field.loading = false
        })
      )
  })
}

const form = createForm({
  effects: () => {
    useAddress('address')
  },
})
const fields = createSchemaField({
  components: {
    FormItem,
    Cascader,
  },
})

export default {
  components: { Form, ...fields, Submit },
  data() {
    return {
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/upload/template.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <Form :form="form" :label-col="4" :wrapper-col="10">
    <ArrayField
      name="upload"
      title="上传"
      :decorator="[FormItem]"
      :component="[
        Upload,
        {
          action: 'https://formily-vue.free.beeceptor.com/file',
          textContent: '上传',
        },
      ]"
      required
    />
    <ArrayField
      name="upload2"
      title="卡片上传"
      :decorator="[FormItem]"
      :component="[
        Upload,
        {
          listType: 'picture-card',
          action: 'https://formily-vue.free.beeceptor.com/file',
        },
      ]"
      required
    />
    <ArrayField
      name="upload3"
      title="拖拽上传"
      :decorator="[FormItem]"
      :component="[
        Upload,
        {
          action: 'https://formily-vue.free.beeceptor.com/file',
          textContent: '将文件拖到此处,或者点击上传',
          drag: true,
        },
      ]"
      required
    />
    <ArrayField
      name="custom"
      title="自定义按钮"
      :decorator="[FormItem]"
      :component="[
        Upload,
        {
          action: 'https://formily-vue.free.beeceptor.com/file',
        },
      ]"
      required
      ><UploadButton
    /></ArrayField>
    <FormButtonGroup align-form-item>
      <Submit @submit="onSubmit">提交</Submit>
    </FormButtonGroup>
  </Form>
</template>

<script>
import { createForm } from '@formily/core'
import { ArrayField } from '@formily/vue'
import {
  Form,
  FormItem,
  Upload,
  Submit,
  FormButtonGroup,
} from '@formily/element'
import { Button } from 'element-ui'

const UploadButton = {
  functional: true,
  render(h) {
    return h(Button, {}, '上传图片')
  },
}

const form = createForm()

export default {
  components: { UploadButton, Form, ArrayField, Submit, FormButtonGroup },
  data() {
    return {
      FormItem,
      Upload,
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField :schema="schema" />
    <Submit @submit="onSubmit">提交</Submit>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField, FormProvider } from '@formily/vue'
import { FormItem, Input, Submit, FormGrid } from '@formily/element'

const schema = {
  type: 'object',
  properties: {
    grid: {
      type: 'void',
      'x-component': 'FormGrid',
      'x-component-props': {
        minColumns: [4, 6, 10],
      },
      properties: {
        aaa: {
          type: 'string',
          title: 'AAA',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        bbb: {
          type: 'string',
          title: 'BBB',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ccc: {
          type: 'string',
          title: 'CCC',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ddd: {
          type: 'string',
          title: 'DDD',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        eee: {
          type: 'string',
          title: 'EEE',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        fff: {
          type: 'string',
          title: 'FFF',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
        ggg: {
          type: 'string',
          title: 'GGG',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
      },
    },
  },
}

const form = createForm()
const { SchemaField } = createSchemaField({
  components: {
    FormItem,
    Input,
    FormGrid,
  },
})

export default {
  components: { FormProvider, SchemaField, Submit },
  data() {
    return {
      form,
      schema,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/core/src/models/Heart.ts:
--------------------------------------------------------------------------------

```typescript
import { isStr, isArr, Subscribable } from '@formily/shared'
import { LifeCycle } from './LifeCycle'
import { IHeartProps } from '../types'
export class Heart<Payload = any, Context = any> extends Subscribable {
  lifecycles: LifeCycle<Payload>[] = []

  outerLifecycles: Map<any, LifeCycle<Payload>[]> = new Map()

  context: Context

  constructor({ lifecycles, context }: IHeartProps<Context> = {}) {
    super()
    this.lifecycles = this.buildLifeCycles(lifecycles || [])
    this.context = context
  }

  buildLifeCycles = (lifecycles: LifeCycle[]) => {
    return lifecycles.reduce((buf, item) => {
      if (item instanceof LifeCycle) {
        return buf.concat(item)
      } else {
        if (isArr(item)) {
          return this.buildLifeCycles(item)
        } else if (typeof item === 'object') {
          this.context = item
          return buf
        }
        return buf
      }
    }, [])
  }

  addLifeCycles = (id: any, lifecycles: LifeCycle[] = []) => {
    const observers = this.buildLifeCycles(lifecycles)
    if (observers.length) {
      this.outerLifecycles.set(id, observers)
    }
  }

  hasLifeCycles = (id: any) => {
    return this.outerLifecycles.has(id)
  }

  removeLifeCycles = (id: any) => {
    this.outerLifecycles.delete(id)
  }

  setLifeCycles = (lifecycles: LifeCycle[] = []) => {
    this.lifecycles = this.buildLifeCycles(lifecycles)
  }

  publish = <P, C>(type: any, payload?: P, context?: C) => {
    if (isStr(type)) {
      this.lifecycles.forEach((lifecycle) => {
        lifecycle.notify(type, payload, context || this.context)
      })
      this.outerLifecycles.forEach((lifecycles) => {
        lifecycles.forEach((lifecycle) => {
          lifecycle.notify(type, payload, context || this.context)
        })
      })
      this.notify({
        type,
        payload,
      })
    }
  }

  clear = () => {
    this.lifecycles = []
    this.outerLifecycles.clear()
    this.unsubscribe()
  }
}

```

--------------------------------------------------------------------------------
/packages/reactive/src/__tests__/tracker.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { Tracker, observable } from '../'

test('base tracker', () => {
  const obs = observable<any>({})
  const fn = jest.fn()
  const view = () => {
    fn(obs.value)
  }
  const scheduler = () => {
    tracker.track(view)
  }
  const tracker = new Tracker(scheduler)

  tracker.track(view)
  obs.value = 123
  expect(fn).nthCalledWith(1, undefined)
  expect(fn).nthCalledWith(2, 123)
  tracker.dispose()
})

test('nested tracker', () => {
  const obs = observable<any>({})
  const fn = jest.fn()
  const view = () => {
    obs.value = obs.value || 321
    fn(obs.value)
  }
  const scheduler = () => {
    tracker.track(view)
  }
  const tracker = new Tracker(scheduler)

  tracker.track(view)
  expect(fn).toBeCalledTimes(1)
  expect(fn).nthCalledWith(1, 321)
  obs.value = 123
  expect(fn).toBeCalledTimes(2)
  expect(fn).nthCalledWith(2, 123)
  tracker.dispose()
})

test('tracker recollect dependencies', () => {
  const obs = observable<any>({
    aa: 'aaa',
    bb: 'bbb',
    cc: 'ccc',
  })
  const fn = jest.fn()
  const view = () => {
    fn()
    if (obs.aa === 'aaa') {
      return obs.bb
    }
    return obs.cc
  }
  const scheduler = () => {
    tracker.track(view)
  }
  const tracker = new Tracker(scheduler)

  tracker.track(view)
  obs.aa = '111'
  obs.bb = '222'
  expect(fn).toBeCalledTimes(2)
  tracker.dispose()
})

test('shared scheduler with multi tracker(mock react strict mode)', () => {
  const obs = observable<any>({})

  const component = () => obs.value

  const render = () => {
    tracker1.track(component)
    tracker2.track(component)
  }

  const scheduler1 = jest.fn(() => {
    tracker2.track(component)
  })
  const scheduler2 = jest.fn(() => {
    tracker1.track(component)
  })
  const tracker1 = new Tracker(scheduler1, 'tracker1')
  const tracker2 = new Tracker(scheduler2, 'tracker2')

  render()

  obs.value = 123

  expect(scheduler1).toBeCalledTimes(1)
  expect(scheduler2).toBeCalledTimes(0)
})

```

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

```typescript
import React from 'react'
import { connect, mapReadPretty } from '@formily/react'
import { Input } from 'antd'
import { PasswordProps } from 'antd/lib/input'
import { PasswordStrength } from './PasswordStrength'
import { PreviewText } from '../preview-text'

export interface IPasswordProps extends PasswordProps {
  checkStrength: boolean
}

export const Password = connect((props: IPasswordProps) => {
  const { value, className, checkStrength, ...others } = props
  const blockStyle: React.CSSProperties = {
    position: 'absolute',
    zIndex: 1,
    height: 8,
    top: 0,
    background: '#fff',
    width: 1,
    transform: 'translate(-50%, 0)',
  }
  return (
    <span className={className}>
      <Input.Password {...others} value={value} />
      {checkStrength && (
        <PasswordStrength value={String(value)}>
          {(score) => {
            return (
              <div
                style={{
                  background: '#e0e0e0',
                  marginBottom: 3,
                  position: 'relative',
                }}
              >
                <div style={{ ...blockStyle, left: '20%' }} />
                <div style={{ ...blockStyle, left: '40%' }} />
                <div style={{ ...blockStyle, left: '60%' }} />
                <div style={{ ...blockStyle, left: '80%' }} />
                <div
                  style={{
                    position: 'relative',
                    backgroundImage:
                      '-webkit-linear-gradient(left, #ff5500, #ff9300)',
                    transition: 'all 0.35s ease-in-out',
                    height: 8,
                    width: '100%',
                    marginTop: 5,
                    clipPath: `polygon(0 0,${score}% 0,${score}% 100%,0 100%)`,
                  }}
                />
              </div>
            )
          }}
        </PasswordStrength>
      )}
    </span>
  )
}, mapReadPretty(PreviewText.Input))

export default Password

```

--------------------------------------------------------------------------------
/packages/react/docs/api/hooks/useField.md:
--------------------------------------------------------------------------------

```markdown
# useField

## Description

Mainly used in custom components to read current field properties, manipulate field status, etc. It can be used in the subtree of all Field components. Note that the one you get is [GeneralField](https://core.formilyjs.org/ api/models/field#generalfield), if you need to process different types of fields, please use [Type Checker](https://core.formilyjs.org/api/entry/form-checker)

<Alert>
Note: If you want to use useField in a custom component and respond to changes in the field model, you need to wrap the observer for the custom component
</Alert>

## Signature

```ts
interface useField {
  (): Field
}
```

## Example

```tsx
import React, { useMemo } from 'react'
import { createForm } from '@formily/core'
import {
  FormProvider,
  FormConsumer,
  Field,
  useField,
  observer,
} from '@formily/react'
import { Input, Form, Button } from 'antd'

// FormItem UI component
const FormItem = observer(({ children }) => {
  const field = useField()
  return (
    <Form.Item
      label={field.title}
      help={field.selfErrors?.length ? field.selfErrors : undefined}
      extra={field.description}
      validateStatus={field.validateStatus}
    >
      {children}
    </Form.Item>
  )
})

export default () => {
  const form = useMemo(() => createForm({ validateFirst: true }))
  return (
    <FormProvider form={form}>
      <Form layout="vertical">
        <Field
          name="name"
          title="Name"
          required
          decorator={[FormItem]}
          component={[Input, { placeholder: 'Please Input' }]}
        />
        <code>
          <pre>
            <FormConsumer>
              {(form) => JSON.stringify(form.values, null, 2)}
            </FormConsumer>
          </pre>
        </code>
        <Button
          type="primary"
          onClick={() => {
            form.submit(console.log)
          }}
        >
          Submit
        </Button>
      </Form>
    </FormProvider>
  )
}
```

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/preview-text/base.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormLayout :labelCol="6" :wrapperCol="10">
    <FormProvider :form="form">
      <SchemaField>
        <SchemaStringField
          x-decorator="FormItem"
          title="文本预览"
          x-component="PreviewText.Input"
          default="Hello world"
        />
        <SchemaStringField
          x-decorator="FormItem"
          title="选择项预览"
          x-component="PreviewText.Select"
          :x-component-props="{
            multiple: true,
          }"
          :default="['123', '222']"
          :enum="[
            { label: 'A111', value: '123' },
            {
              label: 'A222',
              value: '222',
            },
          ]"
        />
        <SchemaStringField
          x-decorator="FormItem"
          title="日期预览"
          x-component="PreviewText.DatePicker"
          default="2020-11-23 22:15:20"
        />
        <SchemaStringField
          x-decorator="FormItem"
          title="时间预览"
          x-component="PreviewText.TimePicker"
          :default="['2020-11-23 22:15:20', '2020-11-23 23:15:20']"
        />
        <SchemaStringField
          x-decorator="FormItem"
          title="Cascader预览"
          x-component="PreviewText.Cascader"
          :default="['hangzhou', 'yuhang']"
          :enum="[
            { label: '杭州', value: 'hangzhou' },
            { label: '余杭', value: 'yuhang' },
          ]"
        />
      </SchemaField>
    </FormProvider>
  </FormLayout>
</template>

<script>
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import { FormLayout, FormItem, PreviewText } from '@formily/element'

const fields = createSchemaField({
  components: {
    FormItem,
    PreviewText,
  },
})

export default {
  components: {
    FormProvider,
    FormLayout,
    ...fields,
  },
  data() {
    const form = createForm()
    return {
      form,
    }
  },
  methods: {
    log(v) {
      console.log(v)
    },
  },
}
</script>

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField :schema="schema" />
    <Submit @submit="log">提交</Submit>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import {
  FormButtonGroup,
  Submit,
  FormItem,
  Space,
  Input,
  ArrayTabs,
} from '@formily/element'
import { Button } from 'element-ui'

const SchemaField = createSchemaField({
  components: {
    FormItem,
    Space,
    Input,
    ArrayTabs,
  },
})

export default {
  components: {
    FormProvider,
    FormButtonGroup,
    Button,
    Submit,
    ...SchemaField,
  },

  data() {
    const form = createForm()
    const schema = {
      type: 'object',
      properties: {
        string_array: {
          type: 'array',
          title: '字符串数组',
          'x-decorator': 'FormItem',
          maxItems: 3,
          'x-component': 'ArrayTabs',
          items: {
            type: 'string',
            'x-decorator': 'FormItem',
            required: true,
            'x-component': 'Input',
          },
        },
        array: {
          type: 'array',
          title: '对象数组',
          'x-decorator': 'FormItem',
          maxItems: 3,
          'x-component': 'ArrayTabs',
          items: {
            type: 'object',
            properties: {
              aaa: {
                type: 'string',
                'x-decorator': 'FormItem',
                title: 'AAA',
                required: true,
                'x-component': 'Input',
              },
              bbb: {
                type: 'string',
                'x-decorator': 'FormItem',
                title: 'BBB',
                required: true,
                'x-component': 'Input',
              },
            },
          },
        },
      },
    }

    return {
      form,
      schema,
    }
  },
  methods: {
    log(values) {
      console.log(values)
    },
  },
}
</script>

<style lang="scss" scoped></style>

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/hooks/use-field.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Form layout="vertical">
      <Field
        name="name"
        title="Name"
        required
        :decorator="[FormItem]"
        :component="[Input, { placeholder: 'Please Input' }]"
      />
      <FormConsumer>
        <template #default="{ form }">
          <div style="white-space: pre; margin-bottom: 16px">
            {{ JSON.stringify(form.values, null, 2) }}
          </div>
          <Button
            type="primary"
            @click="
              () => {
                form.submit(log)
              }
            "
          >
            Submit
          </Button>
        </template>
      </FormConsumer>
    </Form>
  </FormProvider>
</template>

<script>
import { defineComponent, h } from '@vue/composition-api'
import { Form, Input, Button } from 'ant-design-vue'
import { createForm, setValidateLanguage } from '@formily/core'
import { FormProvider, FormConsumer, Field, useField } from '@formily/vue'
import { observer } from '@formily/reactive-vue'
import 'ant-design-vue/dist/antd.css'

setValidateLanguage('en')

const FormItem = observer(
  defineComponent({
    setup(props, { slots }) {
      const fieldRef = useField()
      return () => {
        const field = fieldRef.value
        return h(
          Form.Item,
          {
            props: {
              label: field.title,
              required: field.required,
              help: field.selfErrors?.length ? field.selfErrors : undefined,
              extra: field.description,
              validateStatus: field.validateStatus,
            },
          },
          slots?.default()
        )
      }
    },
  })
)

export default {
  components: {
    FormProvider,
    FormConsumer,
    Field,
    Form,
    Button,
  },
  data() {
    const form = createForm({ validateFirst: true })
    return {
      FormItem,
      Input,
      form,
    }
  },
  methods: {
    log(...args) {
      console.log(...args)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/reactive/src/tree.ts:
--------------------------------------------------------------------------------

```typescript
import { ObModelSymbol, ObModelNodeSymbol, RawNode } from './environment'
import { raw as getRaw } from './externals'
import { PropertyKey, IOperation } from './types'
export class DataChange {
  node: DataNode
  key: PropertyKey
  object: object
  type: string
  value: any
  oldValue: any
  constructor(operation: IOperation, node: DataNode) {
    this.node = node
    this.key = operation.key
    this.type = operation.type
    this.object = operation.target
    this.value = operation.value
    this.oldValue = operation.oldValue
  }

  get path() {
    return this.node.path.concat(this.key)
  }
}
export class DataNode {
  target: any

  key: PropertyKey

  value: any

  constructor(target: any, key: PropertyKey, value: any) {
    this.target = target
    this.key = key
    this.value = value
  }

  get path() {
    if (!this.parent) return this.key ? [this.key] : []
    return this.parent.path.concat(this.key)
  }

  get targetRaw() {
    return getRaw(this.target)
  }

  get parent() {
    if (!this.target) return
    return getDataNode(this.targetRaw)
  }

  isEqual(node: DataNode) {
    if (this.key) {
      return node.targetRaw === this.targetRaw && node.key === this.key
    }
    return node.value === this.value
  }

  contains(node: DataNode) {
    if (node === this) return true
    let parent = node.parent
    while (!!parent) {
      if (this.isEqual(parent)) return true
      parent = parent.parent
    }
    return false
  }
}

export const getDataNode = (raw: any) => {
  if (raw?.[ObModelNodeSymbol]) {
    return raw[ObModelNodeSymbol]
  }
  return RawNode.get(raw)
}

export const setDataNode = (raw: any, node: DataNode) => {
  if (raw?.[ObModelSymbol]) {
    raw[ObModelNodeSymbol] = node
    return
  }
  RawNode.set(raw, node)
}

export const buildDataTree = (target: any, key: PropertyKey, value: any) => {
  const raw = getRaw(value)
  const currentNode = getDataNode(raw)
  if (currentNode) return currentNode
  setDataNode(raw, new DataNode(target, key, value))
}

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/editable/template.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Field
      name="date"
      title="日期"
      :decorator="[Editable]"
      :component="[DatePicker]"
    />
    <Field
      name="input"
      title="输入框"
      :decorator="[Editable]"
      :component="[Input]"
    />
    <VoidField
      name="void"
      title="虚拟节点容器"
      :component="[Editable.Popover]"
      :reactions="
        (field) => {
          field.title = field.query('.void.date2').get('value') || field.title
        }
      "
    >
      <Field
        name="date2"
        title="日期"
        :decorator="[FormItem]"
        :component="[DatePicker]"
      />
      <Field
        name="input2"
        title="输入框"
        :decorator="[FormItem]"
        :component="[Input]"
      />
    </VoidField>
    <ObjectField
      name="iobject"
      title="对象节点容器"
      :component="[Editable.Popover]"
      :reactions="
        (field) => {
          field.title = (field.value && field.value.date) || field.title
        }
      "
    >
      <Field
        name="date"
        title="日期"
        :decorator="[FormItem]"
        :component="[DatePicker]"
      />
      <Field
        name="input"
        title="输入框"
        :decorator="[FormItem]"
        :component="[Input]"
      />
    </ObjectField>

    <FormButtonGroup>
      <Submit @submit="log">提交</Submit>
    </FormButtonGroup>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { FormProvider, Field, VoidField, ObjectField } from '@formily/vue'
import {
  FormButtonGroup,
  FormItem,
  Submit,
  Input,
  DatePicker,
  Editable,
} from '@formily/element'

export default {
  components: {
    FormButtonGroup,
    FormProvider,
    Submit,
    Field,
    VoidField,
    ObjectField,
  },

  data() {
    const form = createForm()

    return {
      FormItem,
      Input,
      DatePicker,
      Editable,
      form,
    }
  },
  methods: {
    log(values) {
      console.log(values)
    },
  },
}
</script>

<style lang="scss" scoped></style>

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/form-item/inset.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <Form :form="form">
    <SchemaField>
      <SchemaStringField
        name="input"
        title="Input"
        x-decorator="FormItem"
        x-component="Input"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
      <SchemaStringField
        name="Select"
        title="Select"
        x-decorator="FormItem"
        x-component="Select"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
      <SchemaStringField
        name="Cascader"
        title="Cascader"
        x-decorator="FormItem"
        x-component="Cascader"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
      <SchemaStringField
        name="DatePicker"
        title="DatePicker"
        x-decorator="FormItem"
        x-component="DatePicker"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
      <SchemaStringField
        name="InputNumber"
        title="InputNumber"
        x-decorator="FormItem"
        x-component="InputNumber"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
      <SchemaBooleanField
        name="Switch"
        title="Switch"
        x-decorator="FormItem"
        x-component="Switch"
        required
        :x-decorator-props="{
          inset: true,
        }"
      />
    </SchemaField>
  </Form>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField } from '@formily/vue'
import {
  Form,
  FormItem,
  Input,
  Select,
  Cascader,
  DatePicker,
  Switch,
  InputNumber,
} from '@formily/element'

const form = createForm()
const fields = createSchemaField({
  components: {
    FormItem,
    Input,
    Select,
    Cascader,
    DatePicker,
    Switch,
    InputNumber,
  },
})

export default {
  components: { Form, ...fields },
  data() {
    return {
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

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

```markdown
# Switch

> 开关组件

## Markup Schema 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Boolean
        name="switch"
        title="开关"
        x-decorator="FormItem"
        x-component="Switch"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## JSON Schema 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    switch: {
      type: 'boolean',
      title: '开关',
      'x-decorator': 'FormItem',
      'x-component': 'Switch',
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## 纯 JSX 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <Field
      name="switch"
      title="开关"
      decorator={[FormItem]}
      component={[Switch]}
    />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

参考 https://ant.design/components/switch-cn/

```

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

```typescript
import { isFn, isValid } from '@formily/shared'
import { LifeCycle, Form } from '../models'
import { AnyFunction } from '../types'
import { isForm } from './checkers'
import { GlobalState } from './constants'

export const createEffectHook = <
  F extends (payload: any, ...ctxs: any[]) => AnyFunction
>(
  type: string,
  callback?: F
) => {
  return (...args: Parameters<ReturnType<F>>) => {
    if (GlobalState.effectStart) {
      GlobalState.lifecycles.push(
        new LifeCycle(type, (payload, ctx) => {
          if (isFn(callback)) {
            callback(payload, ctx, ...GlobalState.context)(...args)
          }
        })
      )
    } else {
      throw new Error(
        'Effect hooks cannot be used in asynchronous function body'
      )
    }
  }
}

export const createEffectContext = <T = any>(defaultValue?: T) => {
  let index: number
  return {
    provide(value?: T) {
      if (GlobalState.effectStart) {
        index = GlobalState.context.length
        GlobalState.context[index] = isValid(value) ? value : defaultValue
      } else {
        throw new Error(
          'Provide method cannot be used in asynchronous function body'
        )
      }
    },
    consume(): T {
      if (!GlobalState.effectStart) {
        throw new Error(
          'Consume method cannot be used in asynchronous function body'
        )
      }
      return GlobalState.context[index]
    },
  }
}

const FormEffectContext = createEffectContext<Form>()

export const useEffectForm = FormEffectContext.consume

export const runEffects = <Context>(
  context?: Context,
  ...args: ((context: Context) => void)[]
): LifeCycle[] => {
  GlobalState.lifecycles = []
  GlobalState.context = []
  GlobalState.effectStart = true
  GlobalState.effectEnd = false
  if (isForm(context)) {
    FormEffectContext.provide(context)
  }
  args.forEach((effects) => {
    if (isFn(effects)) {
      effects(context)
    }
  })
  GlobalState.context = []
  GlobalState.effectStart = false
  GlobalState.effectEnd = true
  return GlobalState.lifecycles
}

```

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

```markdown
# Switch

> 开关组件

## Markup Schema 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Boolean
        name="switch"
        title="开关"
        x-decorator="FormItem"
        x-component="Switch"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## JSON Schema 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    switch: {
      type: 'boolean',
      title: '开关',
      'x-decorator': 'FormItem',
      'x-component': 'Switch',
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## 纯 JSX 案例

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <Field
      name="switch"
      title="开关"
      decorator={[FormItem]}
      component={[Switch]}
    />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

参考 https://fusion.design/pc/component/basic/switch

```

--------------------------------------------------------------------------------
/packages/core/docs/guide/index.md:
--------------------------------------------------------------------------------

```markdown
# Introduction

## Pure Core,No UI

Because @formily/core exists as an independent package, its core meaning is to separate the domain model from the UI framework, and at the same time, it can bring the following two intuitive benefits to developers:

1. It is convenient for formily developers to release from the coupling relationship between UI and logic, and improve code maintainability;

2. Allow formily to have cross-terminal and cross-framework capabilities. Whether you are a React user, Vue user or Angular user, you can enjoy the efficiency improvement brought by formily's domain model.

## Ultra high performance

With the help of @formily/reactive, @formily/core naturally gains the ability to track dependencies, update efficiently, and render on-demand. Whether it is under React or Vue/Angular, whether it is frequent field input or field linkage, it can give Users bring O(1) performance experience, developers do not need to care about performance optimization, only need to focus on business logic implementation.

## Domain Model

If we break down the form question, we can actually break it down:

- Data management issues
- Field management issues
- Calibration management issues
- Linkage management issues

The problems in these directions can actually be solved as domain-level problems. Each domain problem is actually a very complex problem. In Formily, all of them are solved by breakthroughs, so you only need to focus on business logic. That's it.

## Smart tips

Because formily is a complete Typescript project, users can develop on VSCode or WebStorm to get the maximum intelligent prompt experience

![](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)

## Status observable

Install [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) to observe the model status changes in real time and troubleshoot problems

![](//img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/form-item/bordered-none.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <Form :form="form">
    <SchemaField>
      <SchemaStringField
        name="input"
        title="Input"
        x-decorator="FormItem"
        x-component="Input"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
      <SchemaStringField
        name="Select"
        title="Select"
        x-decorator="FormItem"
        x-component="Select"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
      <SchemaStringField
        name="Cascader"
        title="Cascader"
        x-decorator="FormItem"
        x-component="Cascader"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
      <SchemaStringField
        name="DatePicker"
        title="DatePicker"
        x-decorator="FormItem"
        x-component="DatePicker"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
      <SchemaStringField
        name="InputNumber"
        title="InputNumber"
        x-decorator="FormItem"
        x-component="InputNumber"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
      <SchemaBooleanField
        name="Switch"
        title="Switch"
        x-decorator="FormItem"
        x-component="Switch"
        required
        :x-decorator-props="{
          bordered: false,
        }"
      />
    </SchemaField>
  </Form>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField } from '@formily/vue'
import {
  Form,
  FormItem,
  Input,
  Select,
  Cascader,
  DatePicker,
  Switch,
  InputNumber,
} from '@formily/element'

const form = createForm()
const fields = createSchemaField({
  components: {
    FormItem,
    Input,
    Select,
    Cascader,
    DatePicker,
    Switch,
    InputNumber,
  },
})

export default {
  components: { Form, ...fields },
  data() {
    return {
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/components/recursion-field-with-component.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaArrayField name="custom" x-component="ArrayItems">
        <SchemaObjectField>
          <SchemaStringField name="input" x-component="Input" />
        </SchemaObjectField>
      </SchemaArrayField>
    </SchemaField>
  </FormProvider>
</template>

<script>
import { defineComponent, h } from '@vue/composition-api'
// or "import { defineComponent, h } from 'vue'" if using vue3
import { Input, Button, Space } from 'ant-design-vue'
import { createForm } from '@formily/core'
import {
  FormProvider,
  createSchemaField,
  RecursionField,
  useField,
  useFieldSchema,
} from '@formily/vue'
import { observer } from '@formily/reactive-vue'
import 'ant-design-vue/dist/antd.css'

const ArrayItems = observer(
  defineComponent({
    setup() {
      const fieldRef = useField()
      const schemaRef = useFieldSchema()

      return () => {
        const field = fieldRef.value
        const schema = schemaRef.value
        const items = field.value?.map((item, index) => {
          return h('div', { key: item.id, style: { marginBottom: '10px' } }, [
            h(Space, [
              // params of render function is different in vue3
              h(RecursionField, {
                props: { schema: schema.items, name: index },
              }),
              h(Button, { on: { click: () => field.remove(index) } }, [
                'Remove',
              ]),
            ]),
          ])
        })
        const button = h(
          Button,
          { on: { click: () => field.push({ id: Date.now() }) } },
          ['Add']
        )
        return h('div', [items, button])
      }
    },
  })
)

const { SchemaField, SchemaStringField, SchemaArrayField, SchemaObjectField } =
  createSchemaField({
    components: {
      ArrayItems,
      Input,
    },
  })

export default {
  components: {
    FormProvider,
    SchemaField,
    SchemaStringField,
    SchemaArrayField,
    SchemaObjectField,
  },
  data() {
    return {
      form: createForm(),
    }
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/select/markup-schema-async-search.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaStringField
        name="select"
        title="异步搜索选择框"
        x-decorator="FormItem"
        x-component="Select"
        :x-component-props="{
          filterable: true,
          remote: true,
          style: {
            width: '240px',
          },
        }"
      />
    </SchemaField>
    <Submit @submit="log">提交</Submit>
  </FormProvider>
</template>

<script>
import { createForm, onFieldInit, onFieldReact } from '@formily/core'
import { action, observable } from '@formily/reactive'
import { createSchemaField, FormProvider } from '@formily/vue'
import { FormItem, Select, Submit } from '@formily/element'

let timeout
let currentValue

function fetchData(value, callback) {
  if (timeout) {
    clearTimeout(timeout)
    timeout = null
  }
  currentValue = value

  function fake() {
    callback([
      {
        label: 'AAA',
        value: 'aaa',
      },
      {
        label: 'BBB',
        value: 'ccc',
      },
    ])
  }

  timeout = setTimeout(fake, 300)
}

const useAsyncDataSource = (pattern, service) => {
  const keyword = observable.ref('')

  onFieldInit(pattern, (field) => {
    field.setComponentProps({
      remoteMethod: (value) => {
        keyword.value = value
      },
    })
  })

  onFieldReact(pattern, (field) => {
    field.loading = true
    service({ field, keyword: keyword.value }).then(
      action.bound((data) => {
        field.dataSource = data
        field.loading = false
      })
    )
  })
}

const form = createForm({
  effects: () => {
    useAsyncDataSource('select', async ({ keyword }) => {
      if (!keyword) {
        return []
      }
      return new Promise((resolve) => {
        fetchData(keyword, resolve)
      })
    })
  },
})
const fields = createSchemaField({
  components: {
    FormItem,
    Select,
  },
})

export default {
  components: { FormProvider, ...fields, Submit },
  data() {
    return {
      form,
    }
  },
  methods: {
    log(value) {
      console.log(value)
    },
  },
}
</script>

```

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

```markdown
# TimePicker

> 时间选择器

## Markup Schema 案例

```tsx
import React from 'react'
import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    TimePicker,
    FormItem,
  },
})

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="time"
        title="时间"
        x-decorator="FormItem"
        x-component="TimePicker"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## JSON Schema 案例

```tsx
import React from 'react'
import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    TimePicker,
    FormItem,
  },
})

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    time: {
      title: '时间',
      'x-decorator': 'FormItem',
      'x-component': 'TimePicker',
      type: 'string',
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## 纯 JSX 案例

```tsx
import React from 'react'
import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <Field
      name="time"
      title="时间"
      decorator={[FormItem]}
      component={[TimePicker]}
    />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>提交</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

参考 https://fusion.design/pc/component/basic/time-picker

```

--------------------------------------------------------------------------------
/packages/element/src/select/index.ts:
--------------------------------------------------------------------------------

```typescript
import { connect, h, mapProps, mapReadPretty } from '@formily/vue'
import { defineComponent } from 'vue-demi'
import { PreviewText } from '../preview-text'

import type {
  Option as ElOptionProps,
  Select as ElSelectProps,
} from 'element-ui'
import { Option as ElOption, Select as ElSelect } from 'element-ui'
import { resolveComponent } from '../__builtins__'

export type SelectProps = ElSelectProps & {
  options?: Array<ElOptionProps>
}

const SelectOption = defineComponent<SelectProps>({
  name: 'FSelect',
  props: ['options'],
  setup(customProps, { attrs, slots, listeners }) {
    return () => {
      const options = customProps.options || []
      const children =
        options.length !== 0
          ? {
              default: () =>
                options.map((option) => {
                  if (typeof option === 'string') {
                    return h(
                      ElOption,
                      { props: { value: option, label: option } },
                      {
                        default: () => [
                          resolveComponent(slots?.option, { option }),
                        ],
                      }
                    )
                  } else {
                    return h(
                      ElOption,
                      {
                        props: {
                          ...option,
                        },
                      },
                      {
                        default: () => [
                          resolveComponent(slots?.option, {
                            option,
                          }),
                        ],
                      }
                    )
                  }
                }),
            }
          : slots
      return h(
        ElSelect,
        {
          attrs: {
            ...attrs,
          },
          on: listeners,
        },
        children
      )
    }
  },
})

export const Select = connect(
  SelectOption,
  mapProps({ dataSource: 'options', loading: true }),
  mapReadPretty(PreviewText.Select)
)

export default Select

```

--------------------------------------------------------------------------------
/packages/next/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/next",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "umd:main": "dist/formily.next.umd.production.js",
  "unpkg": "dist/formily.next.umd.production.js",
  "jsdelivr": "dist/formily.next.umd.production.js",
  "jsnext:main": "esm",
  "module": "esm",
  "sideEffects": [
    "dist/*",
    "esm/*.js",
    "lib/*.js",
    "src/*.ts",
    "*.scss",
    "**/*/style.js"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "start": "dumi dev",
    "build": "rimraf -rf lib esm dist && npm run create:style && npm run build:cjs && npm run build:esm && npm run build:umd && npm run build:style",
    "create:style": "ts-node create-style",
    "build:style": "ts-node build-style",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config",
    "build:docs": "dumi build"
  },
  "peerDependencies": {
    "@alifd/next": "^1.19.0",
    "@types/react": ">=16.8.0",
    "@types/react-dom": ">=16.8.0",
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "react-is": ">=16.8.0"
  },
  "peerDependenciesMeta": {
    "@types/react": {
      "optional": true
    },
    "@types/react-dom": {
      "optional": true
    }
  },
  "devDependencies": {
    "@umijs/plugin-sass": "^1.1.1",
    "dumi": "^1.1.0-rc.8"
  },
  "dependencies": {
    "@formily/core": "2.3.7",
    "@formily/grid": "2.3.7",
    "@formily/json-schema": "2.3.7",
    "@formily/react": "2.3.7",
    "@formily/reactive": "2.3.7",
    "@formily/reactive-react": "2.3.7",
    "@formily/shared": "2.3.7",
    "classnames": "^2.2.6",
    "react-sortable-hoc": "^1.11.0",
    "react-sticky-box": "^0.9.3"
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

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

```markdown
# Switch

> Switch Components

## Markup Schema example

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Boolean
        name="switch"
        title="Switch"
        x-decorator="FormItem"
        x-component="Switch"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## JSON Schema case

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'

const SchemaField = createSchemaField({
  components: {
    Switch,
    FormItem,
  },
})

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    switch: {
      type: 'boolean',
      title: 'Switch',
      'x-decorator': 'FormItem',
      'x-component': 'Switch',
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## Pure JSX case

```tsx
import React from 'react'
import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <Field
      name="switch"
      title="Switch"
      decorator={[FormItem]}
      component={[Switch]}
    />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

Reference https://ant.design/components/switch-cn/

```

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

```vue
<template>
  <Form :form="form" :label-col="4" :wrapper-col="10">
    <SchemaField>
      <SchemaArrayField
        name="upload"
        title="上传"
        x-decorator="FormItem"
        x-component="Upload"
        :x-component-props="{
          action: 'https://formily-vue.free.beeceptor.com/file',
          textContent: '上传',
        }"
        required
      />
      <SchemaArrayField
        name="upload2"
        title="卡片上传"
        x-decorator="FormItem"
        x-component="Upload"
        :x-component-props="{
          listType: 'picture-card',
          action: 'https://formily-vue.free.beeceptor.com/file',
        }"
        required
      />
      <SchemaArrayField
        name="upload3"
        title="拖拽上传"
        x-decorator="FormItem"
        x-component="Upload"
        :x-component-props="{
          action: 'https://formily-vue.free.beeceptor.com/file',
          textContent: '将文件拖到此处,或者点击上传',
          drag: true,
        }"
        required
      />
      <SchemaArrayField
        name="custom"
        title="自定义按钮"
        x-decorator="FormItem"
        x-component="Upload"
        :x-component-props="{
          action: 'https://formily-vue.free.beeceptor.com/file',
        }"
        required
        :x-content="UploadButton"
      />
    </SchemaField>
    <FormButtonGroup align-form-item>
      <Submit @submit="onSubmit">提交</Submit>
    </FormButtonGroup>
  </Form>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField } from '@formily/vue'
import {
  Form,
  FormItem,
  Upload,
  Submit,
  FormButtonGroup,
} from '@formily/element'
import { Button } from 'element-ui'

const UploadButton = {
  functional: true,
  render(h) {
    return h(Button, {}, '上传图片')
  },
}

const form = createForm()
const fields = createSchemaField({
  components: {
    FormItem,
    Upload,
  },
})

export default {
  components: { Form, ...fields, Submit, FormButtonGroup },
  data() {
    return {
      UploadButton,
      form,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```

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

```vue
<template>
  <Form :form="form">
    <SchemaField
      :schema="schema"
      :scope="{ useAsyncDataSource, transformAddress }"
    />
    <Submit @submit="onSubmit">提交</Submit>
  </Form>
</template>

<script>
import { createForm } from '@formily/core'
import { createSchemaField } from '@formily/vue'
import { Form, FormItem, Cascader, Submit } from '@formily/element'
import { action } from '@formily/reactive'
import axios from 'axios'

const transformAddress = (data = {}) => {
  return Object.entries(data).reduce((buf, [key, value]) => {
    if (typeof value === 'string')
      return buf.concat({
        label: value,
        value: key,
      })
    const { name, code, cities, districts } = value
    const _cities = transformAddress(cities)
    const _districts = transformAddress(districts)
    return buf.concat({
      label: name,
      value: code,
      children: _cities.length
        ? _cities
        : _districts.length
        ? _districts
        : undefined,
    })
  }, [])
}

const useAsyncDataSource = (url, transform) => {
  return (field) => {
    field.loading = true
    axios
      .get(url)
      .then((res) => res.data)
      .then(
        action.bound((data) => {
          field.dataSource = transform(data)
          field.loading = false
        })
      )
  }
}

const schema = {
  type: 'object',
  properties: {
    cascader: {
      type: 'string',
      title: '地址选择',
      'x-decorator': 'FormItem',
      'x-component': 'Cascader',
      'x-component-props': {
        style: {
          width: '240px',
        },
      },
      'x-reactions': [
        '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}',
      ],
    },
  },
}

const form = createForm()
const { SchemaField } = createSchemaField({
  components: {
    FormItem,
    Cascader,
  },
})

export default {
  components: { Form, SchemaField, Submit },
  data() {
    return {
      useAsyncDataSource,
      transformAddress,
      form,
      schema,
    }
  },
  methods: {
    onSubmit(value) {
      console.log(value)
    },
  },
}
</script>

```
Page 5/35FirstPrevNextLast