#
tokens: 49112/50000 31/1152 files (page 9/35)
lines: off (toggle) GitHub
raw markdown copy
This is page 9 of 35. Use http://codebase.md/alibaba/formily?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/validator/src/formats.ts:
--------------------------------------------------------------------------------

```typescript
export default {
  url: new RegExp(
    // protocol identifier
    '^(?:(?:(?:https?|ftp|rtmp):)?//)' +
      // user:pass authentication
      '(?:\\S+(?::\\S*)?@)?' +
      '(?:' +
      // IP address exclusion - private & local networks
      // Reference: https://www.arin.net/knowledge/address_filters.html

      // filter 10.*.*.* and 127.*.*.* addresses
      '(?!(?:10|127)(?:\\.\\d{1,3}){3})' +
      // filter 169.254.*.* and 192.168.*.*
      '(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})' +
      // filter 172.16.0.0 - 172.31.255.255
      // TODO: add test to validate that it invalidates address in 16-31 range
      '(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})' +
      // IP address dotted notation octets
      // excludes loopback network 0.0.0.0
      // excludes reserved space >= 224.0.0.0
      // excludes network & broadcast addresses
      // (first & last IP address of each class)

      // filter 1. part for 1-223
      '(?:22[0-3]|2[01]\\d|[1-9]\\d?|1\\d\\d)' +
      // filter 2. and 3. part for 0-255
      '(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d{1,2})){2}' +
      // filter 4. part for 1-254
      '(?:\\.(?:25[0-4]|2[0-4]\\d|1\\d\\d|[1-9]\\d?))' +
      '|' +
      // host name
      '(?:(?:[a-z\\u00a1-\\uffff0-9_]-*)*[a-z\\u00a1-\\uffff0-9_]+)' +
      // domain name
      '(?:\\.(?:[a-z\\u00a1-\\uffff0-9_]-*)*[a-z\\u00a1-\\uffff0-9_]+)*' +
      // TLD identifier
      '(?:\\.(?:[a-z\\u00a1-\\uffff_]{2,}))' +
      ')' +
      // port number
      '(?::\\d{2,5})?' +
      // resource path
      '(?:/?\\S*)?$'
  ),
  email: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,

  ipv6: /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/,

  ipv4: /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/,

  number: /^[+-]?\d+(\.\d+)?$/,

  integer: /^[+-]?\d+$/,

  qq: /^(\+?[1-9]\d*|0)$/,

  phone: /^\d{3}-\d{8}$|^\d{4}-\d{7}$|^\d{11}$/,

  idcard: /^\d{15}$|^\d{17}(\d|x|X)$/,

  money:
    /^([\u0024\u00A2\u00A3\u00A4\u20AC\u00A5\u20B1\u20B9\uFFE5]\s*)(\d+,?)+(\.\d+)?\s*$/,

  zh: /^[\u4e00-\u9fa5]+$/,

  date: /^[0-9]+[./-][0-9]+[./-][0-9]+\s*(?:[0-9]+\s*:\s*[0-9]+\s*:\s*[0-9]+)?$/,

  zip: /^[0-9]{6}$/,
}

```

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

```typescript
import { toArr, FormPathPattern } from '@formily/shared'
import { define, observable, batch, action } from '@formily/reactive'
import {
  createReactions,
  createStateSetter,
  createStateGetter,
  initializeStart,
  initializeEnd,
} from '../shared/internals'
import {
  IModelSetter,
  IModelGetter,
  IVoidFieldProps,
  IVoidFieldState,
} from '../types'
import { Form } from './Form'
import { BaseField } from './BaseField'

export class VoidField<
  Decorator = any,
  Component = any,
  TextType = any
> extends BaseField<Decorator, Component, TextType> {
  displayName: 'VoidField' = 'VoidField'
  props: IVoidFieldProps<Decorator, Component>

  constructor(
    address: FormPathPattern,
    props: IVoidFieldProps<Decorator, Component>,
    form: Form,
    designable: boolean
  ) {
    super()
    this.form = form
    this.props = props
    this.designable = designable
    initializeStart()
    this.locate(address)
    this.initialize()
    this.makeObservable()
    this.makeReactive()
    this.onInit()
    initializeEnd()
  }

  protected initialize() {
    this.mounted = false
    this.unmounted = false
    this.initialized = false
    this.title = this.props.title
    this.description = this.props.description
    this.pattern = this.props.pattern
    this.display = this.props.display
    this.hidden = this.props.hidden
    this.editable = this.props.editable
    this.disabled = this.props.disabled
    this.readOnly = this.props.readOnly
    this.readPretty = this.props.readPretty
    this.visible = this.props.visible
    this.content = this.props.content
    this.data = this.props.data
    this.decorator = toArr(this.props.decorator)
    this.component = toArr(this.props.component)
  }

  protected makeObservable() {
    if (this.designable) return
    define(this, {
      path: observable.ref,
      title: observable.ref,
      description: observable.ref,
      selfDisplay: observable.ref,
      selfPattern: observable.ref,
      initialized: observable.ref,
      mounted: observable.ref,
      unmounted: observable.ref,
      decoratorType: observable.ref,
      componentType: observable.ref,
      content: observable.ref,
      data: observable.shallow,
      decoratorProps: observable,
      componentProps: observable,
      display: observable.computed,
      pattern: observable.computed,
      hidden: observable.computed,
      visible: observable.computed,
      disabled: observable.computed,
      readOnly: observable.computed,
      readPretty: observable.computed,
      editable: observable.computed,
      component: observable.computed,
      decorator: observable.computed,
      indexes: observable.computed,
      setTitle: action,
      setDescription: action,
      setDisplay: action,
      setPattern: action,
      setComponent: action,
      setComponentProps: action,
      setDecorator: action,
      setDecoratorProps: action,
      setData: action,
      setContent: action,
      onInit: batch,
      onMount: batch,
      onUnmount: batch,
    })
  }

  protected makeReactive() {
    if (this.designable) return
    createReactions(this)
  }

  setState: IModelSetter<IVoidFieldState> = createStateSetter(this)

  getState: IModelGetter<IVoidFieldState> = createStateGetter(this)
}

```

--------------------------------------------------------------------------------
/packages/react/src/components/ReactiveField.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { Fragment, useContext } from 'react'
import { toJS } from '@formily/reactive'
import { observer } from '@formily/reactive-react'
import { FormPath, isFn } from '@formily/shared'
import { isVoidField, GeneralField, Form } from '@formily/core'
import { SchemaComponentsContext } from '../shared'
import { RenderPropsChildren } from '../types'
interface IReactiveFieldProps {
  field: GeneralField
  children?: RenderPropsChildren<GeneralField>
}

const mergeChildren = (
  children: RenderPropsChildren<GeneralField>,
  content: React.ReactNode
) => {
  if (!children && !content) return
  if (isFn(children)) return
  return (
    <Fragment>
      {children}
      {content}
    </Fragment>
  )
}

const isValidComponent = (target: any) =>
  target && (typeof target === 'object' || typeof target === 'function')

const renderChildren = (
  children: RenderPropsChildren<GeneralField>,
  field?: GeneralField,
  form?: Form
) => (isFn(children) ? children(field, form) : children)

const ReactiveInternal: React.FC<IReactiveFieldProps> = (props) => {
  const components = useContext(SchemaComponentsContext)
  if (!props.field) {
    return <Fragment>{renderChildren(props.children)}</Fragment>
  }
  const field = props.field
  const content = mergeChildren(
    renderChildren(props.children, field, field.form),
    field.content ?? field.componentProps.children
  )
  if (field.display !== 'visible') return null

  const getComponent = (target: any) => {
    return isValidComponent(target)
      ? target
      : FormPath.getIn(components, target) ?? target
  }

  const renderDecorator = (children: React.ReactNode) => {
    if (!field.decoratorType) {
      return <Fragment>{children}</Fragment>
    }

    return React.createElement(
      getComponent(field.decoratorType),
      toJS(field.decoratorProps),
      children
    )
  }

  const renderComponent = () => {
    if (!field.componentType) return content
    const value = !isVoidField(field) ? field.value : undefined
    const onChange = !isVoidField(field)
      ? (...args: any[]) => {
          field.onInput(...args)
          field.componentProps?.onChange?.(...args)
        }
      : field.componentProps?.onChange
    const onFocus = !isVoidField(field)
      ? (...args: any[]) => {
          field.onFocus(...args)
          field.componentProps?.onFocus?.(...args)
        }
      : field.componentProps?.onFocus
    const onBlur = !isVoidField(field)
      ? (...args: any[]) => {
          field.onBlur(...args)
          field.componentProps?.onBlur?.(...args)
        }
      : field.componentProps?.onBlur
    const disabled = !isVoidField(field)
      ? field.pattern === 'disabled' || field.pattern === 'readPretty'
      : undefined
    const readOnly = !isVoidField(field)
      ? field.pattern === 'readOnly'
      : undefined
    return React.createElement(
      getComponent(field.componentType),
      {
        disabled,
        readOnly,
        ...toJS(field.componentProps),
        value,
        onChange,
        onFocus,
        onBlur,
      },
      content
    )
  }

  return renderDecorator(renderComponent())
}

ReactiveInternal.displayName = 'ReactiveField'

export const ReactiveField = observer(ReactiveInternal, {
  forwardRef: true,
})

```

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

```typescript
import { Path } from './index'
interface INode {
  type?: string
  after?: Node
  depth?: number
}

export type Node =
  | IdentifierNode
  | WildcardOperatorNode
  | GroupExpressionNode
  | RangeExpressionNode
  | DestructorExpressionNode
  | ObjectPatternNode
  | ArrayPatternNode
  | DotOperatorNode
  | ExpandOperatorNode
  | INode

export type IdentifierNode = {
  type: 'Identifier'
  value: string
  arrayIndex?: boolean
} & INode

export type IgnoreExpressionNode = {
  type: 'IgnoreExpression'
  value: string
} & INode

export type DotOperatorNode = {
  type: 'DotOperator'
} & INode

export type WildcardOperatorNode = {
  type: 'WildcardOperator'
  filter?: GroupExpressionNode | RangeExpressionNode
  optional?: boolean
} & INode

export type ExpandOperatorNode = {
  type: 'ExpandOperator'
} & INode

export type GroupExpressionNode = {
  type: 'GroupExpression'
  value: Node[]
  isExclude?: boolean
} & INode

export type RangeExpressionNode = {
  type: 'RangeExpression'
  start?: IdentifierNode
  end?: IdentifierNode
} & INode

export type DestructorExpressionNode = {
  type: 'DestructorExpression'
  value?: ObjectPatternNode | ArrayPatternNode
  source?: string
} & INode

export type ObjectPatternNode = {
  type: 'ObjectPattern'
  properties: ObjectPatternPropertyNode[]
} & INode

export type ObjectPatternPropertyNode = {
  type: 'ObjectPatternProperty'
  key: IdentifierNode
  value?: ObjectPatternNode[] | ArrayPatternNode[] | IdentifierNode
} & INode

export type ArrayPatternNode = {
  type: 'ArrayPattern'
  elements: ObjectPatternNode[] | ArrayPatternNode[] | IdentifierNode[]
} & INode

export type DestructorRule = {
  key?: string | number
  path?: Array<number | string>
}

export type MatcherFunction = ((path: Segments) => boolean) & {
  path: Path
}

export type Pattern =
  | string
  | number
  | Path
  | Segments
  | MatcherFunction
  | RegExp

export type DestructorRules = DestructorRule[]

export type Segments = Array<string | number>

export const isType =
  <T>(type: string) =>
  (obj: any): obj is T => {
    return obj && obj.type === type
  }

export const isIdentifier = isType<IdentifierNode>('Identifier')

export const isIgnoreExpression =
  isType<IgnoreExpressionNode>('IgnoreExpression')

export const isDotOperator = isType<DotOperatorNode>('DotOperator')

export const isWildcardOperator =
  isType<WildcardOperatorNode>('WildcardOperator')

export const isExpandOperator = isType<ExpandOperatorNode>('ExpandOperator')

export const isGroupExpression = isType<GroupExpressionNode>('GroupExpression')

export const isRangeExpression = isType<RangeExpressionNode>('RangeExpression')

export const isDestructorExpression = isType<DestructorExpressionNode>(
  'DestructorExpression'
)

export const isObjectPattern = isType<ObjectPatternNode>('ObjectPattern')

export const isObjectPatternProperty = isType<ObjectPatternPropertyNode>(
  'ObjectPatternProperty'
)

export const isArrayPattern = isType<ArrayPatternNode>('ArrayPattern')

export type KeyType = string | number | symbol

export type IAccessors = {
  get?: (source: any, key: KeyType) => any
  set?: (source: any, key: KeyType, value: any) => any
  has?: (source: any, key: KeyType) => boolean
  delete?: (source: any, key: KeyType) => any
}

export type IRegistry = {
  accessors?: IAccessors
}

```

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

```vue
<template>
  <Form :form="form">
    <SchemaField>
      <SchemaStringField
        name="size"
        title="Radio.Group"
        x-decorator="FormItem"
        x-component="Radio.Group"
        :enum="[
          { value: 'small', label: 'Small' },
          { value: 'default', label: 'Default' },
          { value: 'large', label: 'Large' },
        ]"
      />
      <SchemaVoidField name="sizeWrap" x-component="Div">
        <SchemaStringField
          name="input"
          title="Input"
          x-decorator="FormItem"
          x-component="Input"
          required
        />
        <SchemaStringField
          name="select1"
          title="Multiple Select"
          x-decorator="FormItem"
          x-component="Select"
          :enum="[
            {
              label: '选项1',
              value: 1,
            },
            {
              label: '选项2',
              value: 2,
            },
          ]"
          :x-component-props="{
            multiple: true,
            placeholder: '请选择',
          }"
          required
        />
        <SchemaStringField
          name="select2"
          title="Select"
          x-decorator="FormItem"
          x-component="Select"
          :enum="[
            {
              label: '选项1',
              value: 1,
            },
            {
              label: '选项2',
              value: 2,
            },
          ]"
          :x-component-props="{
            placeholder: '请选择',
          }"
          required
        />
        <SchemaStringField
          name="Cascader"
          title="Cascader"
          x-decorator="FormItem"
          x-component="Cascader"
          required
        />
        <SchemaStringField
          name="DatePicker"
          title="DatePicker"
          x-decorator="FormItem"
          x-component="DatePicker"
          required
        />
        <SchemaStringField
          name="InputNumber"
          title="InputNumber"
          x-decorator="FormItem"
          x-component="InputNumber"
          required
        />
        <SchemaBooleanField
          name="Switch"
          title="Switch"
          x-decorator="FormItem"
          x-component="Switch"
          required
        />
      </SchemaVoidField>
    </SchemaField>
  </Form>
</template>

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

const Div = {
  functional: true,
  render(h, context) {
    return h('div', context.data, context.children)
  },
}

const form = createForm({
  values: {
    size: 'default',
  },
  effects: () => {
    onFieldChange('size', ['value'], (field, form) => {
      form.setFieldState('sizeWrap.*', (state) => {
        if (state.decorator[1]) {
          state.decorator[1].size = field.value
        }
      })
    })
  },
})
const fields = createSchemaField({
  components: {
    FormItem,
    Input,
    Select,
    Cascader,
    DatePicker,
    Switch,
    InputNumber,
    Radio,
    Div,
  },
})

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

```

--------------------------------------------------------------------------------
/packages/element/src/form-item/grid.scss:
--------------------------------------------------------------------------------

```scss
.#{$form-item-prefix}-item-col-24 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 100%;
  flex: 0 0 100%;
  max-width: 100%;
}

.#{$form-item-prefix}-item-col-23 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 95.83333333%;
  flex: 0 0 95.83333333%;
  max-width: 95.83333333%;
}

.#{$form-item-prefix}-item-col-22 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 91.66666667%;
  flex: 0 0 91.66666667%;
  max-width: 91.66666667%;
}

.#{$form-item-prefix}-item-col-21 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 87.5%;
  flex: 0 0 87.5%;
  max-width: 87.5%;
}

.#{$form-item-prefix}-item-col-20 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 83.33333333%;
  flex: 0 0 83.33333333%;
  max-width: 83.33333333%;
}

.#{$form-item-prefix}-item-col-19 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 79.16666667%;
  flex: 0 0 79.16666667%;
  max-width: 79.16666667%;
}

.#{$form-item-prefix}-item-col-18 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 75%;
  flex: 0 0 75%;
  max-width: 75%;
}

.#{$form-item-prefix}-item-col-17 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 70.83333333%;
  flex: 0 0 70.83333333%;
  max-width: 70.83333333%;
}

.#{$form-item-prefix}-item-col-16 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 66.66666667%;
  flex: 0 0 66.66666667%;
  max-width: 66.66666667%;
}

.#{$form-item-prefix}-item-col-15 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 62.5%;
  flex: 0 0 62.5%;
  max-width: 62.5%;
}

.#{$form-item-prefix}-item-col-14 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 58.33333333%;
  flex: 0 0 58.33333333%;
  max-width: 58.33333333%;
}

.#{$form-item-prefix}-item-col-13 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 54.16666667%;
  flex: 0 0 54.16666667%;
  max-width: 54.16666667%;
}

.#{$form-item-prefix}-item-col-12 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 50%;
  flex: 0 0 50%;
  max-width: 50%;
}

.#{$form-item-prefix}-item-col-11 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 45.83333333%;
  flex: 0 0 45.83333333%;
  max-width: 45.83333333%;
}

.#{$form-item-prefix}-item-col-10 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 41.66666667%;
  flex: 0 0 41.66666667%;
  max-width: 41.66666667%;
}

.#{$form-item-prefix}-item-col-9 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 37.5%;
  flex: 0 0 37.5%;
  max-width: 37.5%;
}

.#{$form-item-prefix}-item-col-8 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 33.33333333%;
  flex: 0 0 33.33333333%;
  max-width: 33.33333333%;
}

.#{$form-item-prefix}-item-col-7 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 29.16666667%;
  flex: 0 0 29.16666667%;
  max-width: 29.16666667%;
}

.#{$form-item-prefix}-item-col-6 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 25%;
  flex: 0 0 25%;
  max-width: 25%;
}

.#{$form-item-prefix}-item-col-5 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 20.83333333%;
  flex: 0 0 20.83333333%;
  max-width: 20.83333333%;
}

.#{$form-item-prefix}-item-col-4 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 16.66666667%;
  flex: 0 0 16.66666667%;
  max-width: 16.66666667%;
}

.#{$form-item-prefix}-item-col-3 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 12.5%;
  flex: 0 0 12.5%;
  max-width: 12.5%;
}

.#{$form-item-prefix}-item-col-2 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 8.33333333%;
  flex: 0 0 8.33333333%;
  max-width: 8.33333333%;
}

.#{$form-item-prefix}-item-col-1 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 4.16666667%;
  flex: 0 0 4.16666667%;
  max-width: 4.16666667%;
}

.#{$form-item-prefix}-item-col-0 {
  display: none;
}

```

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

```typescript
import { isArr, move } from '@formily/shared'
import { action, reaction } from '@formily/reactive'
import {
  spliceArrayState,
  exchangeArrayState,
  cleanupArrayChildren,
} from '../shared/internals'
import { Field } from './Field'
import { Form } from './Form'
import { JSXComponent, IFieldProps, FormPathPattern } from '../types'

export class ArrayField<
  Decorator extends JSXComponent = any,
  Component extends JSXComponent = any
> extends Field<Decorator, Component, any, any[]> {
  displayName = 'ArrayField'

  constructor(
    address: FormPathPattern,
    props: IFieldProps<Decorator, Component>,
    form: Form,
    designable: boolean
  ) {
    super(address, props, form, designable)
    this.makeAutoCleanable()
  }

  protected makeAutoCleanable() {
    this.disposers.push(
      reaction(
        () => this.value?.length,
        (newLength, oldLength) => {
          if (oldLength && !newLength) {
            cleanupArrayChildren(this, 0)
          } else if (newLength < oldLength) {
            cleanupArrayChildren(this, newLength)
          }
        }
      )
    )
  }

  push = (...items: any[]) => {
    return action(() => {
      if (!isArr(this.value)) {
        this.value = []
      }
      this.value.push(...items)
      return this.onInput(this.value)
    })
  }

  pop = () => {
    if (!isArr(this.value)) return
    return action(() => {
      const index = this.value.length - 1
      spliceArrayState(this, {
        startIndex: index,
        deleteCount: 1,
      })
      this.value.pop()
      return this.onInput(this.value)
    })
  }

  insert = (index: number, ...items: any[]) => {
    return action(() => {
      if (!isArr(this.value)) {
        this.value = []
      }
      if (items.length === 0) {
        return
      }
      spliceArrayState(this, {
        startIndex: index,
        insertCount: items.length,
      })
      this.value.splice(index, 0, ...items)
      return this.onInput(this.value)
    })
  }

  remove = (index: number) => {
    if (!isArr(this.value)) return
    return action(() => {
      spliceArrayState(this, {
        startIndex: index,
        deleteCount: 1,
      })
      this.value.splice(index, 1)
      return this.onInput(this.value)
    })
  }

  shift = () => {
    if (!isArr(this.value)) return
    return action(() => {
      this.value.shift()
      return this.onInput(this.value)
    })
  }

  unshift = (...items: any[]) => {
    return action(() => {
      if (!isArr(this.value)) {
        this.value = []
      }
      spliceArrayState(this, {
        startIndex: 0,
        insertCount: items.length,
      })
      this.value.unshift(...items)
      return this.onInput(this.value)
    })
  }

  move = (fromIndex: number, toIndex: number) => {
    if (!isArr(this.value)) return
    if (fromIndex === toIndex) return
    return action(() => {
      move(this.value, fromIndex, toIndex)
      exchangeArrayState(this, {
        fromIndex,
        toIndex,
      })
      return this.onInput(this.value)
    })
  }

  moveUp = (index: number) => {
    if (!isArr(this.value)) return
    return this.move(index, index - 1 < 0 ? this.value.length - 1 : index - 1)
  }

  moveDown = (index: number) => {
    if (!isArr(this.value)) return
    return this.move(index, index + 1 >= this.value.length ? 0 : index + 1)
  }
}

```

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

```typescript
import {
  isValid,
  isFn,
  isMap,
  isWeakMap,
  isSet,
  isWeakSet,
  isPlainObj,
  isArr,
} from './checkers'
import {
  ProxyRaw,
  MakeObModelSymbol,
  DependencyCollected,
  ObModelSymbol,
} from './environment'
import { getDataNode } from './tree'
import { Annotation } from './types'

const RAW_TYPE = Symbol('RAW_TYPE')
const OBSERVABLE_TYPE = Symbol('OBSERVABLE_TYPE')
const hasOwnProperty = Object.prototype.hasOwnProperty

export const isObservable = (target: any) => {
  return ProxyRaw.has(target) || !!target?.[ObModelSymbol]
}

export const isAnnotation = (target: any): target is Annotation => {
  return target && !!target[MakeObModelSymbol]
}

export const isSupportObservable = (target: any) => {
  if (!isValid(target)) return false
  if (isArr(target)) return true
  if (isPlainObj(target)) {
    if (target[RAW_TYPE]) {
      return false
    }
    if (target[OBSERVABLE_TYPE]) {
      return true
    }
    if ('$$typeof' in target && '_owner' in target) {
      return false
    }
    if (target['_isAMomentObject']) {
      return false
    }
    if (target['_isJSONSchemaObject']) {
      return false
    }
    if (isFn(target['toJS'])) {
      return false
    }
    if (isFn(target['toJSON'])) {
      return false
    }
    return true
  }
  if (isMap(target) || isWeakMap(target) || isSet(target) || isWeakSet(target))
    return true
  return false
}

export const markRaw = <T>(target: T): T => {
  if (!target) return
  if (isFn(target)) {
    target.prototype[RAW_TYPE] = true
  } else {
    target[RAW_TYPE] = true
  }
  return target
}

export const markObservable = <T>(target: T): T => {
  if (!target) return
  if (isFn(target)) {
    target.prototype[OBSERVABLE_TYPE] = true
  } else {
    target[OBSERVABLE_TYPE] = true
  }
  return target
}

export const raw = <T>(target: T): T => {
  if (target?.[ObModelSymbol]) return target[ObModelSymbol]
  return ProxyRaw.get(target as any) || target
}

export const toJS = <T>(values: T): T => {
  const visited = new WeakSet<any>()
  const _toJS: typeof toJS = (values: any) => {
    if (visited.has(values)) {
      return values
    }
    if (values && values[RAW_TYPE]) return values
    if (isArr(values)) {
      if (isObservable(values)) {
        visited.add(values)
        const res: any = []
        values.forEach((item: any) => {
          res.push(_toJS(item))
        })
        visited.delete(values)
        return res
      }
    } else if (isPlainObj(values)) {
      if (isObservable(values)) {
        visited.add(values)
        const res: any = {}
        for (const key in values) {
          if (hasOwnProperty.call(values, key)) {
            res[key] = _toJS(values[key])
          }
        }
        visited.delete(values)
        return res
      }
    }
    return values
  }

  return _toJS(values)
}

export const contains = (target: any, property: any) => {
  const targetRaw = raw(target)
  const propertyRaw = raw(property)
  if (targetRaw === propertyRaw) return true
  const targetNode = getDataNode(targetRaw)
  const propertyNode = getDataNode(propertyRaw)
  if (!targetNode) return false
  if (!propertyNode) return false
  return targetNode.contains(propertyNode)
}

export const hasCollected = (callback?: () => void) => {
  DependencyCollected.value = false
  callback?.()
  return DependencyCollected.value
}

```

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

```markdown
# ArrayTabs

> 自增选项卡,对于纵向空间要求较高的场景可以考虑使用该组件
>
> 注意:该组件只适用于 Schema 场景,交互上请避免跨 Tab 联动

## Markup Schema 案例

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <SchemaField>
        <SchemaField.Array
          name="string_array"
          x-decorator="FormItem"
          title="字符串数组"
          maxItems={3}
          x-component="ArrayTabs"
        >
          <SchemaField.String
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField.Array>
        <SchemaField.Array
          name="array"
          x-decorator="FormItem"
          title="对象数组"
          maxItems={3}
          x-component="ArrayTabs"
        >
          <SchemaField.Object>
            <SchemaField.String
              x-decorator="FormItem"
              title="AAA"
              name="aaa"
              required
              x-component="Input"
            />
            <SchemaField.String
              x-decorator="FormItem"
              title="BBB"
              name="bbb"
              required
              x-component="Input"
            />
          </SchemaField.Object>
        </SchemaField.Array>
      </SchemaField>
      <FormButtonGroup>
        <Submit onSubmit={console.log}>提交</Submit>
      </FormButtonGroup>
    </FormProvider>
  )
}
```

## JSON Schema 案例

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

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

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',
          },
        },
      },
    },
  },
}

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

## API

### ArrayTabs

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

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/array-cards/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 {
  FormItem,
  FormButtonGroup,
  Submit,
  Input,
  ArrayCards,
} from '@formily/element'
import { Button } from 'element-ui'

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

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

  data() {
    const form = createForm()
    const schema = {
      type: 'object',
      properties: {
        string_array: {
          type: 'array',
          'x-component': 'ArrayCards',
          maxItems: 3,
          'x-decorator': 'FormItem',
          'x-component-props': {
            title: '字符串数组',
          },
          items: {
            type: 'void',
            properties: {
              index: {
                type: 'void',
                'x-component': 'ArrayCards.Index',
              },
              input: {
                type: 'string',
                'x-decorator': 'FormItem',
                title: 'Input',
                required: true,
                'x-component': 'Input',
              },
              remove: {
                type: 'void',
                'x-component': 'ArrayCards.Remove',
              },
              moveUp: {
                type: 'void',
                'x-component': 'ArrayCards.MoveUp',
              },
              moveDown: {
                type: 'void',
                'x-component': 'ArrayCards.MoveDown',
              },
            },
          },
          properties: {
            addition: {
              type: 'void',
              title: '添加条目',
              'x-component': 'ArrayCards.Addition',
            },
          },
        },
        array: {
          type: 'array',
          'x-component': 'ArrayCards',
          maxItems: 3,
          'x-decorator': 'FormItem',
          'x-component-props': {
            title: '对象数组',
          },
          items: {
            type: 'object',
            properties: {
              index: {
                type: 'void',
                'x-component': 'ArrayCards.Index',
              },
              input: {
                type: 'string',
                'x-decorator': 'FormItem',
                title: 'Input',
                required: true,
                'x-component': 'Input',
              },
              remove: {
                type: 'void',
                'x-component': 'ArrayCards.Remove',
              },
              moveUp: {
                type: 'void',
                'x-component': 'ArrayCards.MoveUp',
              },
              moveDown: {
                type: 'void',
                'x-component': 'ArrayCards.MoveDown',
              },
            },
          },
          properties: {
            addition: {
              type: 'void',
              title: '添加条目',
              'x-component': 'ArrayCards.Addition',
            },
          },
        },
      },
    }

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

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

```

--------------------------------------------------------------------------------
/packages/json-schema/src/__tests__/patches.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { Schema } from '../schema'
import {
  registerTypeDefaultComponents,
  registerVoidComponents,
} from '../polyfills'

registerVoidComponents(['MyCard'])
registerTypeDefaultComponents({
  string: 'Input',
})

Schema.enablePolyfills(['1.0'])

test('v1 polyfill', () => {
  const schema = new Schema({
    type: 'string',
    editable: true,
  } as any)
  expect(schema['x-editable']).toEqual(true)
  const schema1 = new Schema({
    type: 'string',
    visible: true,
  } as any)
  expect(schema1['x-visible']).toEqual(true)
  const schema2 = new Schema({
    type: 'string',
    display: false,
  } as any)
  expect(schema2['x-display']).toEqual('hidden')
  expect(schema2['x-display']).toEqual('hidden')
  const schema3 = new Schema({
    type: 'string',
    'x-linkages': [
      {
        type: 'value:visible',
        condition: '{{$value == 123}}',
      },
    ],
  } as any)
  expect(schema3['x-reactions']).toEqual([
    {
      when: '{{$self.value == 123}}',
      fulfill: {
        state: {
          visible: true,
        },
      },
      otherwise: {
        state: {
          visible: false,
        },
      },
    },
  ])
  const schema4 = new Schema({
    type: 'string',
    'x-linkages': [
      {
        type: 'value:schema',
        target: 'xxx',
        condition: '{{$value == 123}}',
        schema: {
          title: 'xxx',
        },
        otherwise: {
          title: '123',
        },
      },
    ],
  } as any)
  expect(schema4['x-reactions']).toEqual([
    {
      when: '{{$self.value == 123}}',
      target: 'xxx',
      fulfill: {
        schema: {
          version: '1.0',
          title: 'xxx',
          'x-decorator': 'FormItem',
        },
      },
      otherwise: {
        schema: {
          version: '1.0',
          title: '123',
          'x-decorator': 'FormItem',
        },
      },
    },
  ])
  const schema5 = new Schema({
    type: 'string',
    'x-linkages': [
      {
        type: 'value:state',
        target: 'xxx',
        condition: '{{$value == 123}}',
        state: {
          title: 'xxx',
        },
        otherwise: {
          title: '123',
        },
      },
    ],
  } as any)
  expect(schema5['x-reactions']).toEqual([
    {
      when: '{{$self.value == 123}}',
      target: 'xxx',
      fulfill: {
        state: {
          title: 'xxx',
        },
      },
      otherwise: {
        state: {
          title: '123',
        },
      },
    },
  ])
  const schema6 = new Schema({
    type: 'string',
    'x-props': {
      labelCol: 3,
      wrapperCol: 4,
    },
    'x-linkages': [
      {
        type: 'value:visible',
        condition: null,
      },
    ],
  } as any)
  expect(schema6['x-component']).toEqual('Input')
  expect(schema6['x-decorator']).toEqual('FormItem')
  expect(schema6['x-decorator-props']).toEqual({
    labelCol: 3,
    wrapperCol: 4,
  })
  const schema7 = new Schema({
    type: 'object',
    'x-component': 'MyCard',
    'x-linkages': {},
  } as any)
  expect(schema7.type === 'void').toBeTruthy()
  new Schema({
    type: 'object',
    'x-component': 'MyCard',
    'x-linkages': [null],
  } as any)
  new Schema({
    type: 'object',
    'x-component': 'MyCard',
    'x-linkages': [{}],
  } as any)
  const schema8 = new Schema({
    type: 'string',
    'x-rules': ['phone'],
  } as any)
  expect(schema8['x-validator']).toEqual(['phone'])
})

```

--------------------------------------------------------------------------------
/packages/antd/src/form-tab/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { Fragment, useMemo } from 'react'
import { Tabs, Badge } from 'antd'
import { model, markRaw } from '@formily/reactive'
import { TabPaneProps, TabsProps } from 'antd/lib/tabs'
import {
  useField,
  ReactFC,
  observer,
  useFieldSchema,
  RecursionField,
} from '@formily/react'
import { Schema, SchemaKey } from '@formily/json-schema'
import cls from 'classnames'
import { usePrefixCls } from '../__builtins__'
export interface IFormTab {
  activeKey: string
  setActiveKey(key: string): void
}

export interface IFormTabProps extends TabsProps {
  formTab?: IFormTab
}

export interface IFormTabPaneProps extends TabPaneProps {
  key: string | number
}

interface IFeedbackBadgeProps {
  name: SchemaKey
  tab: React.ReactNode
}

type ComposedFormTab = React.FC<React.PropsWithChildren<IFormTabProps>> & {
  TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>>
  createFormTab: (defaultActiveKey?: string) => IFormTab
}

const useTabs = () => {
  const tabsField = useField()
  const schema = useFieldSchema()
  const tabs: { name: SchemaKey; props: any; schema: Schema }[] = []
  schema.mapProperties((schema, name) => {
    const field = tabsField.query(tabsField.address.concat(name)).take()
    if (field?.display === 'none' || field?.display === 'hidden') return
    if (schema['x-component']?.indexOf('TabPane') > -1) {
      tabs.push({
        name,
        props: {
          key: schema?.['x-component-props']?.key || name,
          ...schema?.['x-component-props'],
        },
        schema,
      })
    }
  })
  return tabs
}

const FeedbackBadge: ReactFC<IFeedbackBadgeProps> = observer((props) => {
  const field = useField()
  const errors = field.form.queryFeedbacks({
    type: 'error',
    address: `${field.address.concat(props.name)}.*`,
  })
  if (errors.length) {
    return (
      <Badge size="small" className="errors-badge" count={errors.length}>
        {props.tab}
      </Badge>
    )
  }
  return <Fragment>{props.tab}</Fragment>
})

const createFormTab = (defaultActiveKey?: string) => {
  const formTab = model({
    activeKey: defaultActiveKey,
    setActiveKey(key: string) {
      formTab.activeKey = key
    },
  })
  return markRaw(formTab)
}

export const FormTab: ComposedFormTab = observer(
  ({ formTab, ...props }: IFormTabProps) => {
    const tabs = useTabs()
    const _formTab = useMemo(() => {
      return formTab ? formTab : createFormTab()
    }, [])
    const prefixCls = usePrefixCls('formily-tab', props)
    const activeKey = props.activeKey || _formTab?.activeKey

    return (
      <Tabs
        {...props}
        className={cls(prefixCls, props.className)}
        activeKey={activeKey}
        onChange={(key) => {
          props.onChange?.(key)
          _formTab?.setActiveKey?.(key)
        }}
      >
        {tabs.map(({ props, schema, name }, key) => (
          <Tabs.TabPane
            key={key}
            {...props}
            tab={<FeedbackBadge name={name} tab={props.tab} />}
            forceRender
          >
            <RecursionField schema={schema} name={name} />
          </Tabs.TabPane>
        ))}
      </Tabs>
    )
  }
) as unknown as ComposedFormTab

const TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>> = ({
  children,
}) => {
  return <Fragment>{children}</Fragment>
}

FormTab.TabPane = TabPane
FormTab.createFormTab = createFormTab

export default FormTab

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaArrayField
        name="array"
        x-decorator="FormItem"
        x-component="ArrayTable"
        :x-component-props="{
          pagination: { pageSize: 10 },
        }"
      >
        <SchemaObjectField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            :x-component-props="{ width: 80, title: 'Index' }"
            ><SchemaVoidField
              x-decorator="FormItem"
              x-component="ArrayTable.Index"
            />
          </SchemaVoidField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            :x-component-props="{ prop: 'a1', title: 'A1', width: 200 }"
          >
            <SchemaStringField
              x-decorator="Editable"
              name="a1"
              :required="true"
              x-component="Input"
            />
          </SchemaVoidField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            :x-component-props="{ title: 'A2', width: 200 }"
          >
            <SchemaStringField
              x-decorator="FormItem"
              name="a2"
              :required="true"
              x-component="Input"
            />
          </SchemaVoidField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            :x-component-props="{ title: 'A3' }"
          >
            <SchemaStringField
              name="a3"
              :required="true"
              x-decorator="FormItem"
              x-component="Input"
            />
          </SchemaVoidField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            :x-component-props="{
              title: 'Operations',
              prop: 'operations',
              width: 200,
              fixed: 'right',
            }"
          >
            <SchemaVoidField x-component="FormItem">
              <SchemaVoidField x-component="ArrayTable.Remove" />
              <SchemaVoidField x-component="ArrayTable.MoveUp" />
              <SchemaVoidField x-component="ArrayTable.MoveDown" />
            </SchemaVoidField>
          </SchemaVoidField>
        </SchemaObjectField>
        <SchemaVoidField x-component="ArrayTable.Addition" title="添加条目" />
      </SchemaArrayField>
    </SchemaField>
    <Submit @submit="log">提交</Submit>
    <Button
      @click="
        () => {
          form.setInitialValues({
            array: range(100000),
          })
        }
      "
    >
      加载10W条超大数据
    </Button>
    <Alert
      :style="{ marginTop: '10px' }"
      title="注意:开启formily插件的页面,因为后台有数据通信,会占用浏览器算力,最好在无痕模式(无formily插件)下测试"
      type="warning"
    />
  </FormProvider>
</template>

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

const fields = createSchemaField({
  components: {
    FormItem,
    ArrayTable,
    Input,
    Editable,
  },
})

export default {
  components: { FormProvider, Submit, Button, Alert, ...fields },
  data() {
    const form = createForm()
    return {
      form,
    }
  },
  methods: {
    log(...v) {
      console.log(...v)
    },
    range(count) {
      return Array.from(new Array(count)).map((_, key) => ({
        aaa: key,
      }))
    },
  },
}
</script>

```

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

```typescript
import React, { createContext, useContext } from 'react'
import { useResponsiveFormLayout } from './useResponsiveFormLayout'
import { usePrefixCls } from '../__builtins__'
import cls from 'classnames'

export interface IFormLayoutProps {
  prefix?: string
  className?: string
  style?: React.CSSProperties
  colon?: boolean
  labelAlign?: 'right' | 'left' | ('right' | 'left')[]
  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]
  labelWrap?: boolean
  labelWidth?: number
  wrapperWidth?: number
  wrapperWrap?: boolean
  labelCol?: number | number[]
  wrapperCol?: number | number[]
  fullness?: boolean
  size?: 'small' | 'default' | 'large'
  layout?:
    | 'vertical'
    | 'horizontal'
    | 'inline'
    | ('vertical' | 'horizontal' | 'inline')[]
  direction?: 'rtl' | 'ltr'
  inset?: boolean
  shallow?: boolean
  tooltipLayout?: 'icon' | 'text'
  tooltipIcon?: React.ReactNode
  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none'
  bordered?: boolean
  breakpoints?: number[]
  gridColumnGap?: number
  gridRowGap?: number
  spaceGap?: number
}

export interface IFormLayoutContext
  extends Omit<
    IFormLayoutProps,
    'labelAlign' | 'wrapperAlign' | 'layout' | 'labelCol' | 'wrapperCol'
  > {
  labelAlign?: 'right' | 'left'
  wrapperAlign?: 'right' | 'left'
  layout?: 'vertical' | 'horizontal' | 'inline'
  labelCol?: number
  wrapperCol?: number
}

export const FormLayoutDeepContext = createContext<IFormLayoutContext>(null)

export const FormLayoutShallowContext = createContext<IFormLayoutContext>(null)

export const useFormDeepLayout = () => useContext(FormLayoutDeepContext)

export const useFormShallowLayout = () => useContext(FormLayoutShallowContext)

export const useFormLayout = () => ({
  ...useFormDeepLayout(),
  ...useFormShallowLayout(),
})

export const FormLayout: React.FC<React.PropsWithChildren<IFormLayoutProps>> & {
  useFormLayout: () => IFormLayoutContext
  useFormDeepLayout: () => IFormLayoutContext
  useFormShallowLayout: () => IFormLayoutContext
} = ({ shallow = true, children, prefix, className, style, ...otherProps }) => {
  const { ref, props } = useResponsiveFormLayout(otherProps)
  const deepLayout = useFormDeepLayout()
  const formPrefixCls = usePrefixCls('form', { prefix })
  const layoutPrefixCls = usePrefixCls('formily-layout', { prefix })
  const layoutClassName = cls(
    layoutPrefixCls,
    {
      [`${formPrefixCls}-${props.layout}`]: true,
      [`${formPrefixCls}-rtl`]: props.direction === 'rtl',
      [`${formPrefixCls}-${props.size}`]: props.size,
    },
    className
  )
  const renderChildren = () => {
    const newDeepLayout = {
      ...deepLayout,
    }
    if (!shallow) {
      Object.assign(newDeepLayout, props)
    } else {
      if (props.size) {
        newDeepLayout.size = props.size
      }
      if (props.colon) {
        newDeepLayout.colon = props.colon
      }
    }
    return (
      <FormLayoutDeepContext.Provider value={newDeepLayout}>
        <FormLayoutShallowContext.Provider value={shallow ? props : undefined}>
          {children}
        </FormLayoutShallowContext.Provider>
      </FormLayoutDeepContext.Provider>
    )
  }
  return (
    <div ref={ref} className={layoutClassName} style={style}>
      {renderChildren()}
    </div>
  )
}

FormLayout.useFormDeepLayout = useFormDeepLayout
FormLayout.useFormShallowLayout = useFormShallowLayout
FormLayout.useFormLayout = useFormLayout

export default FormLayout

```

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

```markdown
# Submit

> Submit button

## Ordinary submission

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="input"
        title="input box"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
      <SchemaField.String
        name="input2"
        title="input box"
        default="123"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## Prevent Duplicate Submission (Loading)

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="input"
        title="input box"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
      <SchemaField.String
        name="input2"
        title="input box"
        default="123"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit
        onSubmit={(values) => {
          return new Promise((resolve) => {
            setTimeout(() => {
              console.log(values)
              resolve()
            }, 2000)
          })
        }}
        onSubmitFailed={console.log}
      >
        submit
      </Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

For button-related API properties, we can refer to https://ant.design/components/button-cn/, and the rest are the unique API properties of the Submit component

| Property name   | Type                                                                                             | Description                                               | Default value |
| --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ------------- |
| onClick         | `(event: MouseEvent) => void \| boolean`                                                         | Click event, if it returns false, it can block submission | -             |
| onSubmit        | `(values: any) => Promise<any> \| any`                                                           | Submit event callback                                     | -             |
| onSubmitSuccess | (payload: any) => void                                                                           | Submit successful response event                          | -             |
| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Submit verification failure event callback                | -             |

```

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

```markdown
# Submit

> Submit button

## Ordinary submission

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="input"
        title="input box"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
      <SchemaField.String
        name="input2"
        title="input box"
        default="123"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## Prevent Duplicate Submission (Loading)

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="input"
        title="input box"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
      <SchemaField.String
        name="input2"
        title="input box"
        default="123"
        required
        x-decorator="FormItem"
        x-component="Input"
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit
        onSubmit={(values) => {
          return new Promise((resolve) => {
            setTimeout(() => {
              console.log(values)
              resolve()
            }, 2000)
          })
        }}
        onSubmitFailed={console.log}
      >
        submit
      </Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

For button-related API properties, we can refer to https://fusion.design/pc/component/basic/button, and the rest are the unique API properties of the Submit component

| Property name   | Type                                                                                             | Description                                               | Default value |
| --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ------------- |
| onClick         | `(event: MouseEvent) => void \| boolean`                                                         | Click event, if it returns false, it can block submission | -             |
| onSubmit        | `(values: any) => Promise<any> \| any`                                                           | Submit event callback                                     | -             |
| onSubmitSuccess | (payload: any) => void                                                                           | Submit successful response event                          | -             |
| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Submit verification failure event callback                | -             |

```

--------------------------------------------------------------------------------
/packages/react/docs/api/components/ArrayField.zh-CN.md:
--------------------------------------------------------------------------------

```markdown
---
order: 1
---

# ArrayField

## 描述

作为@formily/core 的 [createArrayField](https://core.formilyjs.org/zh-CN/api/models/form#createarrayfield) React 实现,它是专门用于将 ViewModel 与输入控件做绑定的桥接组件,ArrayField 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)

<Alert>
我们在使用 ArrayField 组件的时候,一定要记得传name属性。同时要使用render props形式来组织子组件
</Alert>

## 签名

```ts
type ArrayField = React.FC<React.PropsWithChildren<IFieldFactoryProps>>
```

## 自定义组件用例

```tsx
import React from 'react'
import { createForm, ArrayField as ArrayFieldType } from '@formily/core'
import {
  FormProvider,
  Field,
  ArrayField,
  useField,
  observer,
} from '@formily/react'
import { Input, Button, Space } from 'antd'

const form = createForm()

const ArrayComponent = observer(() => {
  const field = useField<ArrayFieldType>()
  return (
    <>
      <div>
        {field.value?.map((item, index) => (
          <div key={index} style={{ display: 'flex-block', marginBottom: 10 }}>
            <Space>
              <Field name={index} component={[Input]} />
              <Button
                onClick={() => {
                  field.remove(index)
                }}
              >
                Remove
              </Button>
              <Button
                onClick={() => {
                  field.moveUp(index)
                }}
              >
                Move Up
              </Button>
              <Button
                onClick={() => {
                  field.moveDown(index)
                }}
              >
                Move Down
              </Button>
            </Space>
          </div>
        ))}
      </div>
      <Button
        onClick={() => {
          field.push('')
        }}
      >
        Add
      </Button>
    </>
  )
})

export default () => (
  <FormProvider form={form}>
    <ArrayField name="array" component={[ArrayComponent]} />
  </FormProvider>
)
```

## RenderProps 用例

```tsx
import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, Field, ArrayField } from '@formily/react'
import { Input, Button, Space } from 'antd'

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <ArrayField name="array">
      {(field) => {
        return (
          <>
            <div>
              {field.value?.map((item, index) => (
                <div
                  key={index}
                  style={{ display: 'flex-block', marginBottom: 10 }}
                >
                  <Space>
                    <Field name={index} component={[Input]} />
                    <Button
                      onClick={() => {
                        field.remove(index)
                      }}
                    >
                      Remove
                    </Button>
                    <Button
                      onClick={() => {
                        field.moveUp(index)
                      }}
                    >
                      Move Up
                    </Button>
                    <Button
                      onClick={() => {
                        field.moveDown(index)
                      }}
                    >
                      Move Down
                    </Button>
                  </Space>
                </div>
              ))}
            </div>
            <Button onClick={() => field.push('')}>Add</Button>
          </>
        )
      }}
    </ArrayField>
  </FormProvider>
)
```

```

--------------------------------------------------------------------------------
/packages/antd/src/form-layout/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { createContext, useContext } from 'react'
import { useResponsiveFormLayout } from './useResponsiveFormLayout'
import { usePrefixCls } from '../__builtins__'
import cls from 'classnames'

export interface IFormLayoutProps {
  prefixCls?: string
  className?: string
  style?: React.CSSProperties
  colon?: boolean
  requiredMark?: boolean | 'optional'
  labelAlign?: 'right' | 'left' | ('right' | 'left')[]
  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]
  labelWrap?: boolean
  labelWidth?: number
  wrapperWidth?: number
  wrapperWrap?: boolean
  labelCol?: number | number[]
  wrapperCol?: number | number[]
  fullness?: boolean
  size?: 'small' | 'default' | 'large'
  layout?:
    | 'vertical'
    | 'horizontal'
    | 'inline'
    | ('vertical' | 'horizontal' | 'inline')[]
  direction?: 'rtl' | 'ltr'
  inset?: boolean
  shallow?: boolean
  tooltipLayout?: 'icon' | 'text'
  tooltipIcon?: React.ReactNode
  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none'
  bordered?: boolean
  breakpoints?: number[]
  spaceGap?: number
  gridColumnGap?: number
  gridRowGap?: number
}

export interface IFormLayoutContext
  extends Omit<
    IFormLayoutProps,
    'labelAlign' | 'wrapperAlign' | 'layout' | 'labelCol' | 'wrapperCol'
  > {
  labelAlign?: 'right' | 'left'
  wrapperAlign?: 'right' | 'left'
  layout?: 'vertical' | 'horizontal' | 'inline'
  labelCol?: number
  wrapperCol?: number
}

export const FormLayoutDeepContext = createContext<IFormLayoutContext>(null)

export const FormLayoutShallowContext = createContext<IFormLayoutContext>(null)

export const useFormDeepLayout = () => useContext(FormLayoutDeepContext)

export const useFormShallowLayout = () => useContext(FormLayoutShallowContext)

export const useFormLayout = () => ({
  ...useFormDeepLayout(),
  ...useFormShallowLayout(),
})

export const FormLayout: React.FC<React.PropsWithChildren<IFormLayoutProps>> & {
  useFormLayout: () => IFormLayoutContext
  useFormDeepLayout: () => IFormLayoutContext
  useFormShallowLayout: () => IFormLayoutContext
} = ({
  shallow = true,
  children,
  prefixCls,
  className,
  style,
  ...otherProps
}) => {
  const { ref, props } = useResponsiveFormLayout(otherProps)
  const deepLayout = useFormDeepLayout()
  const formPrefixCls = usePrefixCls('form', { prefixCls })
  const layoutPrefixCls = usePrefixCls('formily-layout', { prefixCls })
  const layoutClassName = cls(
    layoutPrefixCls,
    {
      [`${formPrefixCls}-${props.layout}`]: true,
      [`${formPrefixCls}-rtl`]: props.direction === 'rtl',
      [`${formPrefixCls}-${props.size}`]: props.size,
    },
    className
  )
  const renderChildren = () => {
    const newDeepLayout = {
      ...deepLayout,
    }
    if (!shallow) {
      Object.assign(newDeepLayout, props)
    } else {
      if (props.size) {
        newDeepLayout.size = props.size
      }
      if (props.colon) {
        newDeepLayout.colon = props.colon
      }
    }
    return (
      <FormLayoutDeepContext.Provider value={newDeepLayout}>
        <FormLayoutShallowContext.Provider value={shallow ? props : undefined}>
          {children}
        </FormLayoutShallowContext.Provider>
      </FormLayoutDeepContext.Provider>
    )
  }
  return (
    <div ref={ref} className={layoutClassName} style={style}>
      {renderChildren()}
    </div>
  )
}

FormLayout.useFormDeepLayout = useFormDeepLayout
FormLayout.useFormShallowLayout = useFormShallowLayout
FormLayout.useFormLayout = useFormLayout

export default FormLayout

```

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

```typescript
import React, { Fragment, useMemo } from 'react'
import { Tab as Tabs, Badge } from '@alifd/next'
import { model, markRaw } from '@formily/reactive'
import { isValid } from '@formily/shared'
import {
  ItemProps as TabPaneProps,
  TabProps as TabsProps,
} from '@alifd/next/lib/tab'
import {
  useField,
  observer,
  ReactFC,
  useFieldSchema,
  RecursionField,
} from '@formily/react'
import { Schema, SchemaKey } from '@formily/json-schema'
import cls from 'classnames'
import { usePrefixCls } from '../__builtins__'
export interface IFormTab {
  activeKey: SchemaKey
  setActiveKey(key: SchemaKey): void
}

export interface IFormTabProps extends TabsProps {
  formTab?: IFormTab
}

export interface IFormTabPaneProps extends TabPaneProps {
  key: SchemaKey
}

interface IFeedbackBadgeProps {
  name: SchemaKey
  tab: React.ReactNode
}

type ComposedFormTab = React.FC<React.PropsWithChildren<IFormTabProps>> & {
  TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>>
  createFormTab: (defaultActiveKey?: React.ReactText) => IFormTab
}

const useTabs = () => {
  const tabsField = useField()
  const schema = useFieldSchema()
  const tabs: { name: SchemaKey; props: any; schema: Schema }[] = []
  schema.mapProperties((schema, name) => {
    const field = tabsField.query(tabsField.address.concat(name)).take()
    if (field?.display === 'none' || field?.display === 'hidden') return
    if (schema['x-component']?.indexOf('TabPane') > -1) {
      tabs.push({
        name,
        props: {
          key: schema?.['x-component-props']?.key || name,
          ...schema?.['x-component-props'],
        },
        schema,
      })
    }
  })
  return tabs
}

const createFormTab = (defaultActiveKey?: string) => {
  const formTab = model({
    activeKey: defaultActiveKey,
    setActiveKey(key: string) {
      formTab.activeKey = key
    },
  })
  return markRaw(formTab)
}

const FeedbackBadge: ReactFC<IFeedbackBadgeProps> = observer((props) => {
  const field = useField()
  const errors = field.form.queryFeedbacks({
    type: 'error',
    address: `${field.address.concat(props.name)}.*`,
  })
  if (errors.length) {
    return (
      <Badge className="errors-badge" count={errors.length}>
        {props.tab}
      </Badge>
    )
  }
  return <Fragment>{props.tab}</Fragment>
})

export const FormTab: ComposedFormTab = observer(
  ({ formTab, ...props }: IFormTabProps) => {
    const tabs = useTabs()
    const _formTab = useMemo(() => {
      return formTab ? formTab : createFormTab()
    }, [])
    const prefixCls = usePrefixCls('formily-tab', props)
    const activeKey = props.activeKey || _formTab?.activeKey

    return (
      <Tabs
        {...props}
        {...(isValid(activeKey) && { activeKey })}
        className={cls(prefixCls, props.className)}
        onChange={(key) => {
          props.onChange?.(key)
          _formTab?.setActiveKey?.(key)
        }}
        lazyLoad={false}
      >
        {tabs.map(({ props, schema, name }, key) => (
          <Tabs.Item
            key={key}
            {...props}
            tab={<FeedbackBadge name={name} tab={props.tab} />}
          >
            <RecursionField schema={schema} name={name} />
          </Tabs.Item>
        ))}
      </Tabs>
    )
  }
) as unknown as ComposedFormTab

const TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>> = ({
  children,
}) => {
  return <Fragment>{children}</Fragment>
}

FormTab.TabPane = TabPane
FormTab.createFormTab = createFormTab

export default FormTab

```

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

```markdown
---
order: 3
---

# Form Hooks API

## createEffectHook

#### Description

Create a custom hook listener

#### Signature

```ts
interface createEffectHook {
  (
    type: string,
    callback?: (
      payload: any,
      form: Form,
      ...ctx: any[] //user-injected context
    ) => (...args: any[]) => void //High-level callbacks are used to process the encapsulation of the listener and help users achieve parameter customization capabilities
  )
}
```

#### Example

```tsx
import React, { useMemo, useState } from 'react'
import { createForm, createEffectHook } from '@formily/core'
import { ActionResponse } from './ActionResponse'

const onCustomEvent = createEffectHook(
  'custom-event',
  (payload, form) => (listener) => {
    listener(payload, form)
  }
)

export default () => {
  const [response, setResponse] = useState('')
  const form = useMemo(
    () =>
      createForm({
        effects() {
          onCustomEvent((payload, form) => {
            setResponse(payload + 'Form:' + form.id)
          })
        },
      }),
    []
  )
  return (
    <ActionResponse response={response}>
      <button
        onClick={() => {
          form.notify('custom-event', 'This is Custom Event')
        }}
      >
        Notify
      </button>
    </ActionResponse>
  )
}
```

## createEffectContext

#### Description

In the effects function, if we abstract a lot of fine-grained hooks, we need to pass it layer by layer if we want to read the top-level context data in hooks, which is obviously very inefficient, so formily provides createEffectContext to help users quickly obtain context data

#### Signature

```ts
interface createEffectContext<T> {
  (defaultValue: T): {
    provide(value: T): void
    consume(): T
  }
}
```

#### Example

```tsx
import React, { useMemo, useState } from 'react'
import { createForm, onFormSubmit, createEffectContext } from '@formily/core'
import { ActionResponse } from './ActionResponse'

const { provide, consume } = createEffectContext()

const useMyHook = () => {
  const setResponse = consume()
  onFormSubmit(() => {
    setResponse('Context communication succeeded')
  })
}

export default () => {
  const [response, setResponse] = useState('')
  const form = useMemo(
    () =>
      createForm({
        effects() {
          provide(setResponse)
          useMyHook()
        },
      }),
    []
  )
  return (
    <ActionResponse response={response}>
      <button
        onClick={() => {
          form.submit()
        }}
      >
        submit
      </button>
    </ActionResponse>
  )
}
```

## useEffectForm

#### Description

useEffectForm is actually a convenient usage of EffectContext, because most scene users will read Form instances, so there is no need to manually define an EffectFormContext

#### Signature

```ts
interface useEffectForm {
  (): Form
}
```

#### Example

```tsx
import React, { useMemo, useState } from 'react'
import { createForm, useEffectForm, createEffectContext } from '@formily/core'
import { ActionResponse } from './ActionResponse'

const { provide, consume } = createEffectContext()

const useMyHook = () => {
  const form = useEffectForm()
  const setResponse = consume()
  setResponse('Communication successful:' + form.id)
}

export default () => {
  const [response, setResponse] = useState('')
  useMemo(
    () =>
      createForm({
        effects() {
          provide(setResponse)
          useMyHook()
        },
      }),
    []
  )
  return <ActionResponse response={response} />
}
```

```

--------------------------------------------------------------------------------
/packages/antd/src/form-item/grid.less:
--------------------------------------------------------------------------------

```
.@{form-item-cls} {
  .@{form-item-cls}-item-col-24 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 100%;
    flex: 0 0 100%;
    max-width: 100%;
  }

  .@{form-item-cls}-item-col-23 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 95.83333333%;
    flex: 0 0 95.83333333%;
    max-width: 95.83333333%;
  }

  .@{form-item-cls}-item-col-22 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 91.66666667%;
    flex: 0 0 91.66666667%;
    max-width: 91.66666667%;
  }

  .@{form-item-cls}-item-col-21 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 87.5%;
    flex: 0 0 87.5%;
    max-width: 87.5%;
  }

  .@{form-item-cls}-item-col-20 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 83.33333333%;
    flex: 0 0 83.33333333%;
    max-width: 83.33333333%;
  }

  .@{form-item-cls}-item-col-19 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 79.16666667%;
    flex: 0 0 79.16666667%;
    max-width: 79.16666667%;
  }

  .@{form-item-cls}-item-col-18 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 75%;
    flex: 0 0 75%;
    max-width: 75%;
  }

  .@{form-item-cls}-item-col-17 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 70.83333333%;
    flex: 0 0 70.83333333%;
    max-width: 70.83333333%;
  }

  .@{form-item-cls}-item-col-16 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 66.66666667%;
    flex: 0 0 66.66666667%;
    max-width: 66.66666667%;
  }

  .@{form-item-cls}-item-col-15 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 62.5%;
    flex: 0 0 62.5%;
    max-width: 62.5%;
  }

  .@{form-item-cls}-item-col-14 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 58.33333333%;
    flex: 0 0 58.33333333%;
    max-width: 58.33333333%;
  }

  .@{form-item-cls}-item-col-13 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 54.16666667%;
    flex: 0 0 54.16666667%;
    max-width: 54.16666667%;
  }

  .@{form-item-cls}-item-col-12 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 50%;
    flex: 0 0 50%;
    max-width: 50%;
  }

  .@{form-item-cls}-item-col-11 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 45.83333333%;
    flex: 0 0 45.83333333%;
    max-width: 45.83333333%;
  }

  .@{form-item-cls}-item-col-10 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 41.66666667%;
    flex: 0 0 41.66666667%;
    max-width: 41.66666667%;
  }

  .@{form-item-cls}-item-col-9 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 37.5%;
    flex: 0 0 37.5%;
    max-width: 37.5%;
  }

  .@{form-item-cls}-item-col-8 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 33.33333333%;
    flex: 0 0 33.33333333%;
    max-width: 33.33333333%;
  }

  .@{form-item-cls}-item-col-7 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 29.16666667%;
    flex: 0 0 29.16666667%;
    max-width: 29.16666667%;
  }

  .@{form-item-cls}-item-col-6 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 25%;
    flex: 0 0 25%;
    max-width: 25%;
  }

  .@{form-item-cls}-item-col-5 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 20.83333333%;
    flex: 0 0 20.83333333%;
    max-width: 20.83333333%;
  }

  .@{form-item-cls}-item-col-4 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 16.66666667%;
    flex: 0 0 16.66666667%;
    max-width: 16.66666667%;
  }

  .@{form-item-cls}-item-col-3 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 12.5%;
    flex: 0 0 12.5%;
    max-width: 12.5%;
  }

  .@{form-item-cls}-item-col-2 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 8.33333333%;
    flex: 0 0 8.33333333%;
    max-width: 8.33333333%;
  }

  .@{form-item-cls}-item-col-1 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 4.16666667%;
    flex: 0 0 4.16666667%;
    max-width: 4.16666667%;
  }

  .@{form-item-cls}-item-col-0 {
    display: none;
  }
}

```

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

```markdown
# ArrayTabs

> Self-increasing tab, you can consider using this component for scenarios with high vertical space requirements
>
> Note: This component is only applicable to Schema scenarios, please avoid cross-tab linkage in interaction

## Markup Schema example

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <SchemaField>
        <SchemaField.Array
          name="string_array"
          x-decorator="FormItem"
          title="string array"
          maxItems={3}
          x-component="ArrayTabs"
        >
          <SchemaField.String
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField.Array>
        <SchemaField.Array
          name="array"
          x-decorator="FormItem"
          title="Object array"
          maxItems={3}
          x-component="ArrayTabs"
        >
          <SchemaField.Object>
            <SchemaField.String
              x-decorator="FormItem"
              title="AAA"
              name="aaa"
              required
              x-component="Input"
            />
            <SchemaField.String
              x-decorator="FormItem"
              title="BBB"
              name="bbb"
              required
              x-component="Input"
            />
          </SchemaField.Object>
        </SchemaField.Array>
      </SchemaField>
      <FormButtonGroup>
        <Submit onSubmit={console.log}>Submit</Submit>
      </FormButtonGroup>
    </FormProvider>
  )
}
```

## JSON Schema case

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

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

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    string_array: {
      type: 'array',
      title: 'String array',
      'x-decorator': 'FormItem',
      maxItems: 3,
      'x-component': 'ArrayTabs',
      items: {
        type: 'string',
        'x-decorator': 'FormItem',
        required: true,
        'x-component': 'Input',
      },
    },
    array: {
      type: 'array',
      title: 'Object array',
      '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',
          },
        },
      },
    },
  },
}

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

## API

### ArrayTabs

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

```

--------------------------------------------------------------------------------
/packages/reactive-vue/src/observer/observerInVue2.ts:
--------------------------------------------------------------------------------

```typescript
// https://github.com/mobxjs/mobx-vue/blob/master/src/observer.ts

/**
 * @author Kuitos
 * @homepage https://github.com/kuitos/
 * @since 2018-05-22 16:39
 */
import { Tracker, batch } from '@formily/reactive'
import collectDataForVue from './collectData'
import { Vue2 as Vue } from 'vue-demi'
import { IObserverOptions } from '../types'

const noop = () => {}
const disposerSymbol = Symbol('disposerSymbol')

function observer(Component: any, observerOptions?: IObserverOptions): any {
  const name =
    observerOptions?.name ||
    (Component as any).name ||
    (Component as any)._componentTag ||
    (Component.constructor && Component.constructor.name) ||
    '<component>'

  const originalOptions =
    typeof Component === 'object' ? Component : (Component as any).options
  // To not mutate the original component options, we need to construct a new one
  const dataDefinition = originalOptions.data
  const options = {
    name,
    ...originalOptions,
    data(vm: any) {
      return collectDataForVue(vm || this, dataDefinition)
    },
    // overrider the cached constructor to avoid extending skip
    // @see https://github.com/vuejs/vue/blob/6cc070063bd211229dff5108c99f7d11b6778550/src/core/global-api/extend.js#L24
    _Ctor: {},
  }

  // we couldn't use the Component as super class when Component was a VueClass, that will invoke the lifecycle twice after we called Component.extend
  const superProto =
    typeof Component === 'function' &&
    Object.getPrototypeOf(Component.prototype)
  const Super =
    superProto instanceof (Vue as any) ? superProto.constructor : Vue
  const ExtendedComponent = Super.extend(options)

  const { $mount, $destroy } = ExtendedComponent.prototype

  ExtendedComponent.prototype.$mount = function (this: any, ...args: any[]) {
    let mounted = false
    this[disposerSymbol] = noop

    let nativeRenderOfVue: any

    const reactiveRender = () => {
      batch(() => {
        tracker.track(() => {
          if (!mounted) {
            $mount.apply(this, args)
            mounted = true
            nativeRenderOfVue = this._watcher.getter
            // rewrite the native render method of vue with our reactive tracker render
            // thus if component updated by vue watcher, we could re track and collect dependencies by @formily/reactive
            this._watcher.getter = reactiveRender
          } else {
            nativeRenderOfVue.call(this, this)
          }
        })
      })

      return this
    }

    reactiveRender.$vm = this

    const tracker = new Tracker(() => {
      if (
        reactiveRender.$vm._isBeingDestroyed ||
        reactiveRender.$vm._isDestroyed
      ) {
        return tracker.dispose()
      }

      if (
        observerOptions?.scheduler &&
        typeof observerOptions.scheduler === 'function'
      ) {
        observerOptions.scheduler(reactiveRender)
      } else {
        reactiveRender()
      }
    })

    this[disposerSymbol] = tracker.dispose

    return reactiveRender()
  }

  ExtendedComponent.prototype.$destroy = function (this: any) {
    ;(this as any)[disposerSymbol]()
    $destroy.apply(this)
  }

  const extendedComponentNamePropertyDescriptor =
    Object.getOwnPropertyDescriptor(ExtendedComponent, 'name') || {}
  if (extendedComponentNamePropertyDescriptor.configurable === true) {
    Object.defineProperty(ExtendedComponent, 'name', {
      writable: false,
      value: name,
      enumerable: false,
      configurable: false,
    })
  }

  return ExtendedComponent
}

export { observer, observer as Observer }

```

--------------------------------------------------------------------------------
/packages/next/src/form-item/grid.scss:
--------------------------------------------------------------------------------

```scss
.#{$form-item-cls} {
  .#{$form-item-cls}-item-col-24 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 100%;
    flex: 0 0 100%;
    max-width: 100%;
  }

  .#{$form-item-cls}-item-col-23 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 95.83333333%;
    flex: 0 0 95.83333333%;
    max-width: 95.83333333%;
  }

  .#{$form-item-cls}-item-col-22 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 91.66666667%;
    flex: 0 0 91.66666667%;
    max-width: 91.66666667%;
  }

  .#{$form-item-cls}-item-col-21 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 87.5%;
    flex: 0 0 87.5%;
    max-width: 87.5%;
  }

  .#{$form-item-cls}-item-col-20 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 83.33333333%;
    flex: 0 0 83.33333333%;
    max-width: 83.33333333%;
  }

  .#{$form-item-cls}-item-col-19 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 79.16666667%;
    flex: 0 0 79.16666667%;
    max-width: 79.16666667%;
  }

  .#{$form-item-cls}-item-col-18 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 75%;
    flex: 0 0 75%;
    max-width: 75%;
  }

  .#{$form-item-cls}-item-col-17 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 70.83333333%;
    flex: 0 0 70.83333333%;
    max-width: 70.83333333%;
  }

  .#{$form-item-cls}-item-col-16 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 66.66666667%;
    flex: 0 0 66.66666667%;
    max-width: 66.66666667%;
  }

  .#{$form-item-cls}-item-col-15 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 62.5%;
    flex: 0 0 62.5%;
    max-width: 62.5%;
  }

  .#{$form-item-cls}-item-col-14 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 58.33333333%;
    flex: 0 0 58.33333333%;
    max-width: 58.33333333%;
  }

  .#{$form-item-cls}-item-col-13 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 54.16666667%;
    flex: 0 0 54.16666667%;
    max-width: 54.16666667%;
  }

  .#{$form-item-cls}-item-col-12 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 50%;
    flex: 0 0 50%;
    max-width: 50%;
  }

  .#{$form-item-cls}-item-col-11 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 45.83333333%;
    flex: 0 0 45.83333333%;
    max-width: 45.83333333%;
  }

  .#{$form-item-cls}-item-col-10 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 41.66666667%;
    flex: 0 0 41.66666667%;
    max-width: 41.66666667%;
  }

  .#{$form-item-cls}-item-col-9 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 37.5%;
    flex: 0 0 37.5%;
    max-width: 37.5%;
  }

  .#{$form-item-cls}-item-col-8 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 33.33333333%;
    flex: 0 0 33.33333333%;
    max-width: 33.33333333%;
  }

  .#{$form-item-cls}-item-col-7 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 29.16666667%;
    flex: 0 0 29.16666667%;
    max-width: 29.16666667%;
  }

  .#{$form-item-cls}-item-col-6 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 25%;
    flex: 0 0 25%;
    max-width: 25%;
  }

  .#{$form-item-cls}-item-col-5 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 20.83333333%;
    flex: 0 0 20.83333333%;
    max-width: 20.83333333%;
  }

  .#{$form-item-cls}-item-col-4 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 16.66666667%;
    flex: 0 0 16.66666667%;
    max-width: 16.66666667%;
  }

  .#{$form-item-cls}-item-col-3 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 12.5%;
    flex: 0 0 12.5%;
    max-width: 12.5%;
  }

  .#{$form-item-cls}-item-col-2 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 8.33333333%;
    flex: 0 0 8.33333333%;
    max-width: 8.33333333%;
  }

  .#{$form-item-cls}-item-col-1 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 4.16666667%;
    flex: 0 0 4.16666667%;
    max-width: 4.16666667%;
  }

  .#{$form-item-cls}-item-col-0 {
    display: none;
  }
}

```

--------------------------------------------------------------------------------
/packages/json-schema/src/polyfills/SPECIFICATION_1_0.ts:
--------------------------------------------------------------------------------

```typescript
import { registerPolyfills } from '../patches'
import { toArr, isArr, isStr, lowerCase, isValid } from '@formily/shared'
import { ISchema } from '../types'

const VOID_COMPONENTS = [
  'card',
  'block',
  'grid-col',
  'grid-row',
  'grid',
  'layout',
  'step',
  'tab',
  'text-box',
]

const TYPE_DEFAULT_COMPONENTS = {}

const transformCondition = (condition: string) => {
  if (isStr(condition)) {
    return condition.replace(/\$value/, '$self.value')
  }
}

const transformXLinkage = (linkages: any[]) => {
  if (isArr(linkages)) {
    return linkages.reduce((buf, item) => {
      if (!item) return buf
      if (item.type === 'value:visible') {
        return buf.concat({
          target: item.target,
          when: transformCondition(item.condition),
          fulfill: {
            state: {
              visible: true,
            },
          },
          otherwise: {
            state: {
              visible: false,
            },
          },
        })
      } else if (item.type === 'value:schema') {
        return buf.concat({
          target: item.target,
          when: transformCondition(item.condition),
          fulfill: {
            schema: SpecificationV1Polyfill({ version: '1.0', ...item.schema }),
          },
          otherwise: {
            schema: SpecificationV1Polyfill({
              version: '1.0',
              ...item.otherwise,
            }),
          },
        })
      } else if (item.type === 'value:state') {
        return buf.concat({
          target: item.target,
          when: transformCondition(item.condition),
          fulfill: {
            state: item.state,
          },
          otherwise: {
            state: item.otherwise,
          },
        })
      }
    }, [])
  }
  return []
}

const SpecificationV1Polyfill = (schema: ISchema) => {
  if (isValid(schema['editable'])) {
    schema['x-editable'] = schema['x-editable'] || schema['editable']
    delete schema['editable']
  }
  if (isValid(schema['visible'])) {
    schema['x-visible'] = schema['x-visible'] || schema['visible']
    delete schema['visible']
  }
  if (isValid(schema['display'])) {
    schema['x-display'] =
      schema['x-display'] || (schema['display'] ? 'visible' : 'hidden')
    delete schema['display']
  }
  if (isValid(schema['x-props'])) {
    schema['x-decorator-props'] =
      schema['x-decorator-props'] || schema['x-props']
    delete schema['display']
  }
  if (schema['x-linkages']) {
    schema['x-reactions'] = toArr(schema['x-reactions']).concat(
      transformXLinkage(schema['x-linkages'])
    )
    delete schema['x-linkages']
  }
  if (schema['x-component']) {
    if (
      VOID_COMPONENTS.some(
        (component) => lowerCase(component) === lowerCase(schema['x-component'])
      )
    ) {
      schema['type'] = 'void'
    }
  } else {
    if (TYPE_DEFAULT_COMPONENTS[schema['type']]) {
      schema['x-component'] = TYPE_DEFAULT_COMPONENTS[schema['type']]
    }
  }
  if (
    !schema['x-decorator'] &&
    schema['type'] !== 'void' &&
    schema['type'] !== 'object'
  ) {
    schema['x-decorator'] = schema['x-decorator'] || 'FormItem'
  }
  if (schema['x-rules']) {
    schema['x-validator'] = []
      .concat(schema['x-validator'] || [])
      .concat(schema['x-rules'])
  }
  return schema
}

registerPolyfills('1.0', SpecificationV1Polyfill)

export const registerVoidComponents = (components: string[]) => {
  VOID_COMPONENTS.push(...components)
}

export const registerTypeDefaultComponents = (maps: Record<string, string>) => {
  Object.assign(TYPE_DEFAULT_COMPONENTS, maps)
}

```

--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------

```markdown
---
title: Formily - Alibaba unified front-end form solution
order: 10
hero:
  title: Alibaba Formily
  desc: Alibaba Unified Front-end Form Solution
  actions:
    - text: Introduction
      link: /guide
    - text: Quick start
      link: /guide/quick-start
features:
  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg
    title: Easier to Use
    desc: Out of the box, rich cases
  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg
    title: More Efficient
    desc: Fool writing, ultra-high performance
  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg
    title: More Professional
    desc: Complete, flexible and elegant
footer: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self
---

```tsx
/**
 * inline: true
 */
import React from 'react'
import { Section } from './site/Section'
import './site/styles.less'

export default () => (
  <Section
    title="Fool Writing, Ultra-high Performance"
    style={{ marginTop: 40 }}
    titleStyle={{ paddingBottom: 100, fontWeight: 'bold' }}
  >
    <iframe
      className="codesandbox"
      src="https://codesandbox.io/embed/formilyyaliceshi-vbu4w?fontsize=12&module=%2FApp.tsx&theme=dark"
      allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
      sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
    ></iframe>
  </Section>
)
```

```tsx
/**
 * inline: true
 */
import React from 'react'
import { Section } from './site/Section'
import './site/styles.less'

export default () => (
  <Section
    title="Form Builder,Efficient Development"
    style={{ marginTop: 140, fontWeight: 'bold' }}
    titleStyle={{ paddingBottom: 140 }}
    scale={1.2}
  >
    <a href="//designable-antd.formilyjs.org" target="_blank" rel="noreferrer">
      <img src="//img.alicdn.com/imgextra/i2/O1CN01eI9FLz22tZek2jv7E_!!6000000007178-2-tps-3683-2272.png" />
    </a>
  </Section>
)
```

```tsx
/**
 * inline: true
 */
import React from 'react'
import { Section } from './site/Section'
import './site/styles.less'

export default () => (
  <Section
    title="Pure Core, More Extensibility"
    style={{ marginTop: 140 }}
    titleStyle={{ paddingBottom: 100, fontWeight: 'bold' }}
  >
    <a href="//core.formilyjs.org" target="_blank" rel="noreferrer">
      <img src="//img.alicdn.com/imgextra/i4/O1CN019qbf1b1ChnTfT9x3X_!!6000000000113-55-tps-1939-1199.svg" />
    </a>
  </Section>
)
```

```tsx
/**
 * inline: true
 */
import React from 'react'
import { Section } from './site/Section'
import { Contributors } from './site/Contributors'
import './site/styles.less'

export default () => (
  <Section
    title="Active Community & Genius People"
    style={{ marginTop: 100 }}
    titleStyle={{ paddingBottom: 140, fontWeight: 'bold' }}
  >
    <Contributors />
  </Section>
)
```

```tsx
/**
 * inline: true
 */
import React from 'react'
import { Section } from './site/Section'
import { QrCode, QrCodeGroup } from './site/QrCode'
import './site/styles.less'

export default () => (
  <Section
    title="High-Quality Community Group"
    style={{ marginTop: 140 }}
    titleStyle={{ paddingBottom: 20, fontWeight: 'bold' }}
  >
    <QrCodeGroup>
      <QrCode link="//img.alicdn.com/imgextra/i1/O1CN011zlc5b1uu1BDUpNg1_!!6000000006096-2-tps-978-1380.png" />
    </QrCodeGroup>
  </Section>
)
```

```

--------------------------------------------------------------------------------
/packages/vue/src/shared/connect.ts:
--------------------------------------------------------------------------------

```typescript
import { isVue2, markRaw, defineComponent, getCurrentInstance } from 'vue-demi'
import { isFn, isStr, FormPath, each, isValid } from '@formily/shared'
import { isVoidField, GeneralField } from '@formily/core'
import { observer } from '@formily/reactive-vue'

import { useField } from '../hooks/useField'
import h from './h'

import type {
  VueComponent,
  IComponentMapper,
  IStateMapper,
  VueComponentProps,
} from '../types'

export function mapProps<T extends VueComponent = VueComponent>(
  ...args: IStateMapper<VueComponentProps<T>>[]
) {
  const transform = (input: VueComponentProps<T>, field: GeneralField) =>
    args.reduce((props, mapper) => {
      if (isFn(mapper)) {
        props = Object.assign(props, mapper(props, field))
      } else {
        each(mapper, (to, extract) => {
          const extractValue = FormPath.getIn(field, extract)
          const targetValue = isStr(to) ? to : extract
          const originalValue = FormPath.getIn(props, targetValue)
          if (extract === 'value') {
            if (to !== extract) {
              delete props['value']
            }
          }
          if (isValid(originalValue) && !isValid(extractValue)) return
          FormPath.setIn(props, targetValue, extractValue)
        })
      }
      return props
    }, input)

  return (target: T) => {
    return observer(
      defineComponent({
        name: target.name ? `Connected${target.name}` : `ConnectedComponent`,
        setup(props, { attrs, slots, listeners }: any) {
          const fieldRef = useField()
          return () => {
            const newAttrs = fieldRef.value
              ? transform({ ...attrs } as VueComponentProps<T>, fieldRef.value)
              : { ...attrs }
            return h(
              target,
              {
                attrs: newAttrs,
                on: listeners,
              },
              slots
            )
          }
        },
      })
    )
  }
}

export function mapReadPretty<T extends VueComponent, C extends VueComponent>(
  component: C,
  readPrettyProps?: Record<string, any>
) {
  return (target: T) => {
    return observer(
      defineComponent({
        name: target.name ? `Read${target.name}` : `ReadComponent`,
        setup(props, { attrs, slots, listeners }: Record<string, any>) {
          const fieldRef = useField()
          return () => {
            const field = fieldRef.value
            return h(
              field && !isVoidField(field) && field.pattern === 'readPretty'
                ? component
                : target,
              {
                attrs: {
                  ...readPrettyProps,
                  ...attrs,
                },
                on: listeners,
              },
              slots
            )
          }
        },
      })
    )
  }
}

export function connect<T extends VueComponent>(
  target: T,
  ...args: IComponentMapper[]
): T {
  const Component = args.reduce((target: VueComponent, mapper) => {
    return mapper(target)
  }, target)
  /* istanbul ignore else */
  if (isVue2) {
    const functionalComponent = defineComponent({
      functional: true,
      name: target.name,
      render(h, context) {
        return h(Component, context.data, context.children)
      },
    })
    return markRaw(functionalComponent) as T
  } else {
    const functionalComponent = defineComponent({
      name: target.name,
      setup(props, { attrs, slots }) {
        return () => {
          return h(Component, { props, attrs }, slots)
        }
      },
    })
    return markRaw(functionalComponent) as T
  }
}

```

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

```typescript
import {
  Segments,
  Node,
  DestructorRules,
  isArrayPattern,
  isObjectPattern,
  isIdentifier,
  isDestructorExpression,
} from './types'
import { isNum } from './shared'

type Mutators = {
  getIn: (segments: Segments, source: any) => any
  setIn: (segments: Segments, source: any, value: any) => void
  deleteIn?: (segments: Segments, source: any) => any
  existIn?: (segments: Segments, source: any, start: number) => boolean
}

const DestructorCache = new Map()

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

export const getDestructor = (source: string) => {
  return DestructorCache.get(source)
}

export const setDestructor = (source: string, rules: DestructorRules) => {
  DestructorCache.set(source, rules)
}

export const parseDestructorRules = (node: Node): DestructorRules => {
  const rules = []
  if (isObjectPattern(node)) {
    let index = 0
    node.properties.forEach((child) => {
      rules[index] = {
        path: [],
      }
      rules[index].key = child.key.value
      rules[index].path.push(child.key.value)
      if (isIdentifier(child.value)) {
        rules[index].key = child.value.value
      }
      const basePath = rules[index].path
      const childRules = parseDestructorRules(child.value as Node)
      let k = index
      childRules.forEach((rule) => {
        if (rules[k]) {
          rules[k].key = rule.key
          rules[k].path = basePath.concat(rule.path)
        } else {
          rules[k] = {
            key: rule.key,
            path: basePath.concat(rule.path),
          }
        }
        k++
      })
      if (k > index) {
        index = k
      } else {
        index++
      }
    })
    return rules
  } else if (isArrayPattern(node)) {
    let index = 0
    node.elements.forEach((child, key) => {
      rules[index] = {
        path: [],
      }
      rules[index].key = key
      rules[index].path.push(key)
      if (isIdentifier(child)) {
        rules[index].key = child.value
      }
      const basePath = rules[index].path
      const childRules = parseDestructorRules(child as Node)
      let k = index
      childRules.forEach((rule) => {
        if (rules[k]) {
          rules[k].key = rule.key
          rules[k].path = basePath.concat(rule.path)
        } else {
          rules[k] = {
            key: rule.key,
            path: basePath.concat(rule.path),
          }
        }
        k++
      })
      if (k > index) {
        index = k
      } else {
        index++
      }
    })
    return rules
  }
  if (isDestructorExpression(node)) {
    return parseDestructorRules(node.value)
  }
  return rules
}

export const setInByDestructor = (
  source: any,
  rules: DestructorRules,
  value: any,
  mutators: Mutators
) => {
  rules.forEach(({ key, path }) => {
    mutators.setIn([key], source, mutators.getIn(path, value))
  })
}

export const getInByDestructor = (
  source: any,
  rules: DestructorRules,
  mutators: Mutators
) => {
  let response = {}
  if (rules.length) {
    if (isNum(rules[0].path[0])) {
      response = []
    }
  }
  source = isValid(source) ? source : {}
  rules.forEach(({ key, path }) => {
    mutators.setIn(path, response, source[key])
  })
  return response
}

export const deleteInByDestructor = (
  source: any,
  rules: DestructorRules,
  mutators: Mutators
) => {
  rules.forEach(({ key }) => {
    mutators.deleteIn([key], source)
  })
}

export const existInByDestructor = (
  source: any,
  rules: DestructorRules,
  start: number,
  mutators: Mutators
) => {
  return rules.every(({ key }) => {
    return mutators.existIn([key], source, start)
  })
}

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaBooleanField
        name="hideFirstColumn"
        x-decorator="FormItem"
        x-component="Switch"
        title="隐藏A2"
      />
      <SchemaArrayField
        name="array"
        x-decorator="FormItem"
        x-component="ArrayTable"
      >
        <SchemaObjectField>
          <SchemaVoidField
            name="column1"
            x-component="ArrayTable.Column"
            :x-component-props="{ width: 80, title: 'Index' }"
            ><SchemaVoidField x-component="ArrayTable.Index" />
          </SchemaVoidField>
          <SchemaVoidField
            name="column2"
            x-component="ArrayTable.Column"
            :x-component-props="{
              title: '显隐->A2',
              width: 100,
            }"
          >
            <SchemaBooleanField
              name="a1"
              x-decorator="FormItem"
              x-component="Switch"
            />
          </SchemaVoidField>
          <SchemaVoidField
            x-component="ArrayTable.Column"
            name="column3"
            :x-component-props="{ title: 'A2', width: 200 }"
          >
            <SchemaStringField
              x-decorator="FormItem"
              name="a2"
              x-component="Input"
            />
          </SchemaVoidField>
          <SchemaVoidField
            name="column4"
            x-component="ArrayTable.Column"
            :x-component-props="{ title: 'A3' }"
          >
            <SchemaStringField
              name="a3"
              x-decorator="FormItem"
              x-component="Input"
            />
          </SchemaVoidField>
          <SchemaVoidField
            name="column5"
            x-component="ArrayTable.Column"
            :x-component-props="{
              title: 'Operations',
              prop: 'operations',
              width: 200,
              fixed: 'right',
            }"
          >
            <SchemaVoidField x-component="FormItem">
              <SchemaVoidField x-component="ArrayTable.Remove" />
              <SchemaVoidField x-component="ArrayTable.MoveUp" />
              <SchemaVoidField x-component="ArrayTable.MoveDown" />
            </SchemaVoidField>
          </SchemaVoidField>
        </SchemaObjectField>
        <SchemaVoidField x-component="ArrayTable.Addition" title="添加条目" />
      </SchemaArrayField>
    </SchemaField>
    <Submit @submit="log">提交</Submit>
  </FormProvider>
</template>

<script>
import { createForm, onFieldChange, onFieldReact } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import {
  Submit,
  FormItem,
  ArrayTable,
  Input,
  Editable,
  Switch,
} from '@formily/element'

const fields = createSchemaField({
  components: {
    FormItem,
    ArrayTable,
    Input,
    Editable,
    Switch,
  },
})

export default {
  components: { FormProvider, Submit, ...fields },
  data() {
    const form = createForm({
      effects: () => {
        //主动联动模式
        onFieldChange('hideFirstColumn', ['value'], (field) => {
          field.query('array.column3').take((target) => {
            console.log('target', target)
            target.visible = !field.value
          })
          field.query('array.*.a2').take((target) => {
            target.visible = !field.value
          })
        })
        //被动联动模式
        onFieldReact('array.*.a2', (field) => {
          field.visible = !field.query('.a1').get('value')
        })
      },
    })

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

```

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

```typescript
import { isFn, isCollectionType, isNormalType } from './checkers'
import {
  RawProxy,
  ProxyRaw,
  MakeObModelSymbol,
  RawShallowProxy,
} from './environment'
import { baseHandlers, collectionHandlers } from './handlers'
import { buildDataTree, getDataNode } from './tree'
import { isSupportObservable } from './externals'
import { PropertyKey, IVisitor, BoundaryFunction } from './types'

const createNormalProxy = (target: any, shallow?: boolean) => {
  const proxy = new Proxy(target, baseHandlers)
  ProxyRaw.set(proxy, target)
  if (shallow) {
    RawShallowProxy.set(target, proxy)
  } else {
    RawProxy.set(target, proxy)
  }
  return proxy
}

const createCollectionProxy = (target: any, shallow?: boolean) => {
  const proxy = new Proxy(target, collectionHandlers)
  ProxyRaw.set(proxy, target)
  if (shallow) {
    RawShallowProxy.set(target, proxy)
  } else {
    RawProxy.set(target, proxy)
  }
  return proxy
}

const createShallowProxy = (target: any) => {
  if (isNormalType(target)) return createNormalProxy(target, true)
  if (isCollectionType(target)) return createCollectionProxy(target, true)
  // never reach
  return target
}

export const createObservable = (
  target: any,
  key?: PropertyKey,
  value?: any,
  shallow?: boolean
) => {
  if (typeof value !== 'object') return value
  const raw = ProxyRaw.get(value)
  if (!!raw) {
    const node = getDataNode(raw)
    if (!node.target) node.target = target
    node.key = key
    return value
  }

  if (!isSupportObservable(value)) return value

  if (target) {
    const parentRaw = ProxyRaw.get(target) || target
    const isShallowParent = RawShallowProxy.get(parentRaw)
    if (isShallowParent) return value
  }

  buildDataTree(target, key, value)
  if (shallow) return createShallowProxy(value)
  if (isNormalType(value)) return createNormalProxy(value)
  if (isCollectionType(value)) return createCollectionProxy(value)
  // never reach
  return value
}

export const createAnnotation = <T extends (visitor: IVisitor) => any>(
  maker: T
) => {
  const annotation = (target: any): ReturnType<T> => {
    return maker({ value: target })
  }
  if (isFn(maker)) {
    annotation[MakeObModelSymbol] = maker
  }
  return annotation
}

export const getObservableMaker = (target: any) => {
  if (target[MakeObModelSymbol]) {
    if (!target[MakeObModelSymbol][MakeObModelSymbol]) {
      return target[MakeObModelSymbol]
    }
    return getObservableMaker(target[MakeObModelSymbol])
  }
}

export const createBoundaryFunction = (
  start: (...args: any) => void,
  end: (...args: any) => void
) => {
  function boundary<F extends (...args: any) => any>(fn?: F): ReturnType<F> {
    let results: ReturnType<F>
    try {
      start()
      if (isFn(fn)) {
        results = fn()
      }
    } finally {
      end()
    }
    return results
  }

  boundary.bound = createBindFunction(boundary)
  return boundary
}

export const createBindFunction = <Boundary extends BoundaryFunction>(
  boundary: Boundary
) => {
  function bind<F extends (...args: any[]) => any>(
    callback?: F,
    context?: any
  ): F {
    return ((...args: any[]) =>
      boundary(() => callback.apply(context, args))) as any
  }
  return bind
}

export const createBoundaryAnnotation = (
  start: (...args: any) => void,
  end: (...args: any) => void
) => {
  const boundary = createBoundaryFunction(start, end)
  const annotation = createAnnotation(({ target, key }) => {
    target[key] = boundary.bound(target[key], target)
    return target
  })
  boundary[MakeObModelSymbol] = annotation
  boundary.bound[MakeObModelSymbol] = annotation
  return boundary
}

```

--------------------------------------------------------------------------------
/packages/antd/src/__builtins__/sort.tsx:
--------------------------------------------------------------------------------

```typescript
import { DndContext, DragEndEvent, DragStartEvent } from '@dnd-kit/core'
import {
  SortableContext,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { ReactFC } from '@formily/reactive-react'
import React, { createContext, useContext, useMemo } from 'react'

export interface ISortableContainerProps {
  list: any[]
  start?: number
  accessibility?: {
    container?: Element
  }
  onSortStart?: (event: DragStartEvent) => void
  onSortEnd?: (event: { oldIndex: number; newIndex: number }) => void
}

export function SortableContainer<T extends React.HTMLAttributes<HTMLElement>>(
  Component: ReactFC<T>
): ReactFC<ISortableContainerProps & T> {
  return ({
    list,
    start = 0,
    accessibility,
    onSortStart,
    onSortEnd,
    ...props
  }) => {
    const _onSortEnd = (event: DragEndEvent) => {
      const { active, over } = event
      const oldIndex = (active.id as number) - 1
      const newIndex = (over?.id as number) - 1
      onSortEnd?.({
        oldIndex,
        newIndex,
      })
    }

    return (
      <DndContext
        accessibility={accessibility}
        onDragStart={onSortStart}
        onDragEnd={_onSortEnd}
      >
        <SortableContext
          items={list.map((_, index) => index + start + 1)}
          strategy={verticalListSortingStrategy}
        >
          <Component {...(props as unknown as T)}>{props.children}</Component>
        </SortableContext>
      </DndContext>
    )
  }
}

export const useSortableItem = () => {
  return useContext(SortableItemContext)
}

export const SortableItemContext = createContext<
  Partial<ReturnType<typeof useSortable>>
>({})

export interface ISortableElementProps {
  index?: number
  lockAxis?: 'x' | 'y'
}

export function SortableElement<T extends React.HTMLAttributes<HTMLElement>>(
  Component: ReactFC<T>
): ReactFC<T & ISortableElementProps> {
  return ({ index = 0, lockAxis, ...props }) => {
    const sortable = useSortable({
      id: index + 1,
    })
    const { setNodeRef, transform, transition, isDragging } = sortable
    if (transform) {
      switch (lockAxis) {
        case 'x':
          transform.y = 0
          break
        case 'y':
          transform.x = 0
          break
        default:
          break
      }
    }

    const style = useMemo(() => {
      const itemStyle: React.CSSProperties = {
        position: 'relative',
        touchAction: 'none',
        zIndex: 1,
        transform: `translate3d(${transform?.x || 0}px, ${
          transform?.y || 0
        }px, 0)`,
        transition: `${transform ? 'all 200ms ease' : ''}`,
      }
      const dragStyle: React.CSSProperties = {
        transition,
        opacity: '0.8',
        transform: `translate3d(${transform?.x || 0}px, ${
          transform?.y || 0
        }px, 0)`,
      }

      const computedStyle = isDragging
        ? {
            ...itemStyle,
            ...dragStyle,
            ...props.style,
          }
        : {
            ...itemStyle,
            ...props.style,
          }

      return computedStyle
    }, [isDragging, transform, transition, props.style])

    return (
      <SortableItemContext.Provider value={sortable}>
        {Component({
          ...props,
          style,
          ref: setNodeRef,
        } as unknown as T)}
      </SortableItemContext.Provider>
    )
  }
}

export function SortableHandle<T extends React.HTMLAttributes<HTMLElement>>(
  Component: ReactFC<T>
): ReactFC<T> {
  return (props: T) => {
    const { attributes, listeners } = useSortableItem()
    return <Component {...props} {...attributes} {...listeners} />
  }
}

```
Page 9/35FirstPrevNextLast