#
tokens: 49742/50000 80/1152 files (page 4/35)
lines: off (toggle) GitHub
raw markdown copy
This is page 4 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

--------------------------------------------------------------------------------
/devtools/chrome-extension/src/app/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { useState } from 'react'
import { LeftPanel } from './components/LeftPanel'
import { RightPanel } from './components/RightPanel'
import styled from 'styled-components'

export default styled(({ className, dataSource }) => {
  const [selected, select] = useState({
    current: 0,
    key: '',
  })
  return (
    <div className={className}>
      <LeftPanel
        dataSource={dataSource}
        onSelect={(info) => {
          select(info)
          if (chrome && chrome.devtools && chrome.devtools.inspectedWindow) {
            chrome.devtools.inspectedWindow.eval(
              `window.__FORMILY_DEV_TOOLS_HOOK__.setVm("${info.key}","${
                dataSource[info.current][''].id
              }")`
            )
          }
        }}
      />
      <RightPanel
        dataSource={
          selected
            ? (dataSource &&
                dataSource[selected.current] &&
                dataSource[selected.current][selected.key]) ||
              {}
            : {}
        }
      />
    </div>
  )
})`
  display: flex;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
  color: #36d4c7;
  background: #282c34;
`

```

--------------------------------------------------------------------------------
/packages/reactive/src/annotations/box.ts:
--------------------------------------------------------------------------------

```typescript
import { ProxyRaw, RawProxy } from '../environment'
import { createAnnotation } from '../internals'
import { buildDataTree } from '../tree'
import {
  bindTargetKeyWithCurrentReaction,
  runReactionsFromTargetKey,
} from '../reaction'

export interface IBox {
  <T>(target: T): { get(): T; set(value: T): void }
}

export const box: IBox = createAnnotation(({ target, key, value }) => {
  const store = {
    value: target ? target[key] : value,
  }

  const proxy = {
    set,
    get,
  }

  ProxyRaw.set(proxy, store)
  RawProxy.set(store, proxy)

  buildDataTree(target, key, store)

  function get() {
    bindTargetKeyWithCurrentReaction({
      target: store,
      key,
      type: 'get',
    })
    return store.value
  }

  function set(value: any) {
    const oldValue = store.value
    store.value = value
    if (oldValue !== value) {
      runReactionsFromTargetKey({
        target: store,
        key,
        type: 'set',
        oldValue,
        value,
      })
    }
  }

  if (target) {
    Object.defineProperty(target, key, {
      value: proxy,
      enumerable: true,
      configurable: false,
      writable: false,
    })
    return target
  }
  return proxy
})

```

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

```markdown
# useFieldSchema

## Description

Mainly read the Schema information of the current field in the custom component, this hook can only be used in the subtree of SchemaField or RecursionField

## Signature

```ts
interface useFieldSchema {
  (): Schema
}
```

Schema Reference [Schema](/api/shared/schema)

## Example

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

const form = createForm()

const Custom = () => {
  const schema = useFieldSchema()
  return (
    <code>
      <pre>{JSON.stringify(schema.toJSON(), null, 2)}</pre>
    </code>
  )
}

const SchemaField = createSchemaField({
  components: {
    Custom,
  },
})

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Object
        name="custom"
        x-component="Custom"
        x-component-props={{
          schema: {
            type: 'object',
            properties: {
              input: {
                type: 'string',
                'x-component': 'Custom',
              },
            },
          },
        }}
      />
    </SchemaField>
  </FormProvider>
)
```

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/components/expression-scope.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <SchemaField :scope="{ $outerScope: 'outer scope value' }">
      <SchemaVoidField x-component="Container">
        <SchemaVoidField
          name="div"
          x-component="Text"
          :x-component-props="{ text: `{{$innerScope + ' ' + $outerScope}}` }"
        />
      </SchemaVoidField>
    </SchemaField>
  </FormProvider>
</template>

<script>
import { defineComponent } from '@vue/composition-api'
import { createForm } from '@formily/core'
import {
  FormProvider,
  h,
  createSchemaField,
  ExpressionScope,
} from '@formily/vue'

const Container = defineComponent({
  setup(_props, { slots }) {
    return () =>
      h(
        ExpressionScope,
        {
          props: { value: { $innerScope: 'inner scope value' } },
        },
        slots
      )
  },
})
const Text = defineComponent({
  props: ['text'],
  setup(props) {
    return () => h('div', {}, { default: () => props.text })
  },
})
const SchemaField = createSchemaField({
  components: { Container, Text },
})

export default {
  components: { FormProvider, ...SchemaField },
  data() {
    return {
      Text,
      form: createForm(),
    }
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/json-schema/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/json-schema",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "module": "esm",
  "umd:main": "dist/formily.json-schema.umd.production.js",
  "unpkg": "dist/formily.json-schema.umd.production.js",
  "jsdelivr": "dist/formily.json-schema.umd.production.js",
  "jsnext:main": "esm",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config"
  },
  "peerDependencies": {
    "typescript": ">4.1.5"
  },
  "dependencies": {
    "@formily/core": "2.3.7",
    "@formily/reactive": "2.3.7",
    "@formily/shared": "2.3.7"
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

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

```typescript
import { IOperation } from './types'
import { ObserverListeners } from './environment'
import { raw as getRaw } from './externals'
import { isFn } from './checkers'
import { DataChange, getDataNode } from './tree'

export const observe = (
  target: object,
  observer?: (change: DataChange) => void,
  deep = true
) => {
  const addListener = (target: any) => {
    const raw = getRaw(target)
    const node = getDataNode(raw)

    const listener = (operation: IOperation) => {
      const targetRaw = getRaw(operation.target)
      const targetNode = getDataNode(targetRaw)
      if (deep) {
        if (node.contains(targetNode)) {
          observer(new DataChange(operation, targetNode))
          return
        }
      }
      if (
        node === targetNode ||
        (node.targetRaw === targetRaw && node.key === operation.key)
      ) {
        observer(new DataChange(operation, targetNode))
      }
    }

    if (node && isFn(observer)) {
      ObserverListeners.add(listener)
    }
    return () => {
      ObserverListeners.delete(listener)
    }
  }
  if (target && typeof target !== 'object')
    throw Error(`Can not observe ${typeof target} type.`)
  return addListener(target)
}

```

--------------------------------------------------------------------------------
/packages/element/src/date-picker/index.ts:
--------------------------------------------------------------------------------

```typescript
import { transformComponent } from '../__builtins__/shared'
import { connect, mapProps, mapReadPretty } from '@formily/vue'

import type { DatePicker as ElDatePickerProps } from 'element-ui'
import { DatePicker as ElDatePicker } from 'element-ui'
import { PreviewText } from '../preview-text'

export type DatePickerProps = ElDatePickerProps

const TransformElDatePicker = transformComponent<DatePickerProps>(
  ElDatePicker,
  {
    change: 'input',
  }
)

const getDefaultFormat = (props, formatType = 'format') => {
  const type = props.type

  if (type === 'week' && formatType === 'format') {
    return 'yyyy-WW'
  } else if (type === 'month') {
    return 'yyyy-MM'
  } else if (type === 'year') {
    return 'yyyy'
  } else if (type === 'datetime' || type === 'datetimerange') {
    return 'yyyy-MM-dd HH:mm:ss'
  }

  return 'yyyy-MM-dd'
}

export const DatePicker = connect(
  TransformElDatePicker,
  mapProps({ readOnly: 'readonly' }, (props) => {
    return {
      ...props,
      format: props.format || getDefaultFormat(props),
      valueFormat: props.valueFormat || getDefaultFormat(props, 'valueFormat'),
    }
  }),
  mapReadPretty(PreviewText.DatePicker)
)

export default DatePicker

```

--------------------------------------------------------------------------------
/packages/antd/src/array-table/style.less:
--------------------------------------------------------------------------------

```
@root-entry-name: 'default';
@import (reference) '~antd/es/style/themes/index.less';

@array-table-prefix-cls: ~'@{ant-prefix}-formily-array-table';

.@{array-table-prefix-cls} {
  .@{array-table-prefix-cls}-pagination {
    display: flex;
    justify-content: center;

    .@{array-table-prefix-cls}-status-select.has-error {
      .@{ant-prefix}-select-selector {
        border-color: @error-color !important;
      }
    }
  }

  .@{ant-prefix}-table {
    table {
      overflow: hidden;
    }

    td {
      visibility: visible;

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

        .@{ant-prefix}-formily-item-help {
          position: absolute;
          font-size: 12px;
          top: 100%;
          background: #fff;
          width: 100%;
          margin-top: 3px;
          padding: 3px;
          z-index: 1;
          border-radius: 3px;
          box-shadow: 0 0 10px #eee;
          animation: none;
          transform: translateY(0);
          opacity: 1;
        }
      }
    }
  }

  .@{array-table-prefix-cls}-sort-helper {
    background: #fff;
    border: 1px solid #eee;
    z-index: 10;
  }
}

```

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

```typescript
import React from 'react'
import { Button } from 'antd'
import { ButtonProps } from 'antd/lib/button'
import { IFormFeedback } from '@formily/core'
import { useParentForm, observer } from '@formily/react'

export interface ISubmitProps extends ButtonProps {
  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any
  onSubmit?: (values: any) => any
  onSubmitSuccess?: (payload: any) => void
  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void
}

export const Submit: React.FC<React.PropsWithChildren<ISubmitProps>> = observer(
  ({ onSubmit, onSubmitFailed, onSubmitSuccess, ...props }: ISubmitProps) => {
    const form = useParentForm()
    return (
      <Button
        htmlType={onSubmit ? 'button' : 'submit'}
        type="primary"
        {...props}
        loading={props.loading !== undefined ? props.loading : form.submitting}
        onClick={(e) => {
          if (props.onClick) {
            if (props.onClick(e) === false) return
          }
          if (onSubmit) {
            form.submit(onSubmit).then(onSubmitSuccess).catch(onSubmitFailed)
          }
        }}
      >
        {props.children}
      </Button>
    )
  },
  {
    forwardRef: true,
  }
)

export default Submit

```

--------------------------------------------------------------------------------
/packages/vue/src/utils/getFieldProps.ts:
--------------------------------------------------------------------------------

```typescript
export const getFieldProps = () => ({
  name: {},
  title: {},
  description: {},
  value: {},
  initialValue: {},
  basePath: {},
  decorator: Array,
  component: Array,
  display: String,
  pattern: String,
  required: { type: Boolean, default: undefined },
  validateFirst: { type: Boolean, default: undefined },
  hidden: { type: Boolean, default: undefined },
  visible: { type: Boolean, default: undefined },
  editable: { type: Boolean, default: undefined },
  disabled: { type: Boolean, default: undefined },
  readOnly: { type: Boolean, default: undefined },
  readPretty: { type: Boolean, default: undefined },
  dataSource: {},
  validator: {},
  reactions: [Array, Function],
})

export const getVoidFieldProps = () => ({
  name: {},
  title: {},
  description: {},
  basePath: {},
  decorator: Array,
  component: Array,
  display: String,
  pattern: String,
  hidden: { type: Boolean, default: undefined },
  visible: { type: Boolean, default: undefined },
  editable: { type: Boolean, default: undefined },
  disabled: { type: Boolean, default: undefined },
  readOnly: { type: Boolean, default: undefined },
  readPretty: { type: Boolean, default: undefined },
  reactions: [Array, Function],
})

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/guide/submit/loading.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaStringField
        required
        name="input1"
        title="输入框"
        x-decorator="FormItem"
        x-component="Input"
      />
      <SchemaStringField
        required
        title="输入框"
        name="input2"
        x-decorator="FormItem"
        x-component="Input"
      />
    </SchemaField>
    <FormButtonGroup align-form-item>
      <Submit @submit="handleSubmit">提交</Submit>
    </FormButtonGroup>
  </FormProvider>
</template>

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

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

export default {
  components: {
    FormProvider,
    FormLayout,
    Submit,
    FormButtonGroup,
    ...fields,
  },
  data() {
    const form = createForm()
    return {
      form,
    }
  },
  methods: {
    handleSubmit(values) {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(values)
          resolve()
        }, 2000)
      })
    },
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/next/src/__builtins__/moment.ts:
--------------------------------------------------------------------------------

```typescript
import { isArr, isEmpty, isFn } from '@formily/shared'
import Moment from 'moment'

const moment = (date: any, format?: string) => {
  return Moment(date?.toDate ? date.toDate() : date, format)
}

export const momentable = (value: any, format?: string) => {
  return Array.isArray(value)
    ? value.map((val) => moment(val, format))
    : value
    ? moment(value, format)
    : value
}

export const formatMomentValue = (
  value: any,
  format: any,
  placeholder?: string
): string | string[] => {
  const formatDate = (date: any, format: any, i = 0) => {
    if (!date) return placeholder
    const TIME_REG = /^(?:[01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/
    let _format = format
    if (isArr(format)) {
      _format = format[i]
    }
    if (isFn(_format)) {
      return _format(date)
    }
    if (isEmpty(_format)) {
      return date
    }
    // moment '19:55:22' 下需要传入第二个参数
    if (TIME_REG.test(date)) {
      return moment(date, _format).format(_format)
    }
    return moment(date).format(_format)
  }
  if (isArr(value)) {
    return value.map((val, index) => {
      return formatDate(val, format, index)
    })
  } else {
    return value ? formatDate(value, format) : value || placeholder
  }
}

```

--------------------------------------------------------------------------------
/packages/shared/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/shared",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "module": "esm",
  "umd:main": "dist/formily.shared.umd.production.js",
  "unpkg": "dist/formily.shared.umd.production.js",
  "jsdelivr": "dist/formily.shared.umd.production.js",
  "jsnext:main": "esm",
  "types": "esm/index.d.ts",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283",
  "scripts": {
    "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config"
  },
  "dependencies": {
    "@formily/path": "2.3.7",
    "camel-case": "^4.1.1",
    "lower-case": "^2.0.1",
    "no-case": "^3.0.4",
    "param-case": "^3.0.4",
    "pascal-case": "^3.1.1",
    "upper-case": "^2.0.1"
  }
}

```

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

```typescript
import React from 'react'
import { Button } from '@alifd/next'
import { ButtonProps } from '@alifd/next/lib/button'
import { IFormFeedback } from '@formily/core'
import { useParentForm, observer } from '@formily/react'

interface ISubmitProps extends ButtonProps {
  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any
  onSubmit?: (values: any) => any
  onSubmitSuccess?: (payload: any) => void
  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void
}

export const Submit: React.FC<React.PropsWithChildren<ISubmitProps>> = observer(
  ({ onSubmit, onSubmitFailed, onSubmitSuccess, ...props }: ISubmitProps) => {
    const form = useParentForm()
    return (
      <Button
        htmlType={onSubmit ? 'button' : 'submit'}
        type="primary"
        {...props}
        loading={props.loading !== undefined ? props.loading : form.submitting}
        onClick={(e) => {
          if (props.onClick) {
            if (props.onClick(e) === false) return
          }
          if (onSubmit) {
            form.submit(onSubmit).then(onSubmitSuccess).catch(onSubmitFailed)
          }
        }}
      >
        {props.children}
      </Button>
    )
  },
  {
    forwardRef: true,
  }
)

export default Submit

```

--------------------------------------------------------------------------------
/packages/reactive/docs/api/markRaw.md:
--------------------------------------------------------------------------------

```markdown
# markRaw

## Description

Mark any object or class prototype as never being hijacked by observable, priority is higher than markObservable

Note: If you mark an object that is already observable with markRaw, then toJS will not convert it into a normal object

## Signature

```ts
interface markRaw<T> {
  (target: T): T
}
```

## Example

```ts
import { observable, autorun, markRaw } from '@formily/reactive'

class A {
  property = ''
}

const a = observable(new A())

autorun(() => {
  console.log(a.property) //It will be triggered when the property changes, because the A instance is a normal object
})

a.property = 123

//--------------------------------------------

const b = observable(markRaw(new A())) //instance-level mark, only valid for the current instance

autorun(() => {
  console.log(b.property) //will not be triggered when the property changes, because it has been marked raw
})

b.property = 123

//--------------------------------------------

markRaw(A) //Class-level mark, then all instances will take effect

const c = observable(new A())

autorun(() => {
  console.log(c.property) //will not be triggered when the property changes, because it has been marked raw
})

c.property = 123
```

```

--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------

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

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/components/void-field.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Space>
      <VoidField name="layout">
        <Field name="input" :component="[Input]" />
      </VoidField>
      <FormConsumer>
        <template #default="{ form }">
          <Space>
            <Button
              @click="
                () => {
                  form
                    .query('layout')
                    .take()
                    .setState((state) => {
                      state.visible = !state.visible
                    })
                }
              "
            >
              {{ form.query('layout').get('visible') ? 'Hide' : 'Show' }}
            </Button>
            <div>{{ JSON.stringify(form.values, null, 2) }}</div>
          </Space>
        </template>
      </FormConsumer>
    </Space>
  </FormProvider>
</template>

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

export default {
  components: { FormProvider, Field, FormConsumer, VoidField, Space, Button },
  data() {
    return {
      Input,
      form: createForm(),
    }
  },
}
</script>

```

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

```markdown
# useExpressionScope

## Description

The expression scope is mainly read in the custom component. The sources of the expression scope are:

- createSchemaField top-level delivery
- SchemaField component attribute delivery
- ExpressionScope/RecordScope/RecordsScope are issued inside custom components

## Signature

```ts
interface useExpressionScope {
  (): any
}
```

## Example

```tsx
import React from 'react'
import { createForm } from '@formily/core'
import {
  FormProvider,
  createSchemaField,
  useExpressionScope,
  RecordScope,
} from '@formily/react'

const form = createForm()

const Custom = () => {
  const scope = useExpressionScope()
  return (
    <code>
      <pre>{JSON.stringify(scope, null, 2)}</pre>
    </code>
  )
}

const SchemaField = createSchemaField({
  components: {
    Custom,
  },
  scope: {
    topScope: {
      aa: 123,
    },
  },
})

export default () => (
  <FormProvider form={form}>
    <RecordScope
      getRecord={() => ({ name: 'Record Name', code: 'Record Code' })}
      getIndex={() => 2}
    >
      <SchemaField scope={{ propsScope: { bb: 321 } }}>
        <SchemaField.String name="custom" x-component="Custom" />
      </SchemaField>
    </RecordScope>
  </FormProvider>
)
```

```

--------------------------------------------------------------------------------
/packages/reactive/docs/api/vue/observer.md:
--------------------------------------------------------------------------------

```markdown
# observer

## describe

In Vue, the component rendering method is changed to Reaction, and dependencies are collected every time the view is re-rendered, and dependencies are updated automatically to re-render.

### Signature

```ts
interface IObserverOptions {
  scheduler?: (updater: () => void) => void //The scheduler, you can manually control the timing of the update
  name?: string //name of the packaged component
}

interface observer<T extends VueComponent> {
  (component: T, options?: IObserverOptions): T
}
```

## Example

```html
<template>
  <div>
    <div>
      <input
        :style="{
           height: 28,
           padding: '0 8px',
           border: '2px solid #888',
           borderRadius: 3,
         }"
        :value="obs.value"
        @input="(e) => {
           obs.value = e.target.value
         }"
      />
    </div>
    <div>{{obs.value}}</div>
  </div>
</template>

<script>
  import { observable } from '@formily/reactive'
  import { observer } from '@formily/reactive-vue'

  export default observer({
    data() {
      // can coexist with vue's response system
      const obs = observable({
        value: 'Hello world',
      })
      return {
        obs,
      }
    },
  })
</script>
```

```

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

```typescript
import moment from 'moment'
import { connect, mapProps, mapReadPretty } from '@formily/react'
import { TimePicker as AntdTimePicker } from 'antd'
import {
  TimePickerProps as AntdTimePickerProps,
  TimeRangePickerProps,
} from 'antd/lib/time-picker'
import { PreviewText } from '../preview-text'
import { formatMomentValue, momentable } from '../__builtins__'

type ComposedTimePicker = React.FC<
  React.PropsWithChildren<AntdTimePickerProps>
> & {
  RangePicker?: React.FC<React.PropsWithChildren<TimeRangePickerProps>>
}

const mapTimeFormat = function () {
  return (props: any) => {
    const format = props['format'] || 'HH:mm:ss'
    const onChange = props.onChange
    return {
      ...props,
      format,
      value: momentable(props.value, format),
      onChange: (value: moment.Moment | moment.Moment[]) => {
        if (onChange) {
          onChange(formatMomentValue(value, format))
        }
      },
    }
  }
}

export const TimePicker: ComposedTimePicker = connect(
  AntdTimePicker,
  mapProps(mapTimeFormat()),
  mapReadPretty(PreviewText.TimePicker)
)

TimePicker.RangePicker = connect(
  AntdTimePicker.RangePicker,
  mapProps(mapTimeFormat()),
  mapReadPretty(PreviewText.TimeRangePicker)
)

export default TimePicker

```

--------------------------------------------------------------------------------
/packages/element/src/__builtins__/shared/utils.ts:
--------------------------------------------------------------------------------

```typescript
import { onMounted, ref } from 'vue-demi'

export function isValidElement(element) {
  return (
    isVueOptions(element) ||
    (element &&
      typeof element === 'object' &&
      'componentOptions' in element &&
      'context' in element &&
      element.tag !== undefined)
  ) // remove text node
}

export function isVnode(element: any): boolean {
  return (
    element &&
    typeof element === 'object' &&
    'componentOptions' in element &&
    'context' in element &&
    element.tag !== undefined
  )
}

export function isVueOptions(options) {
  return (
    options &&
    (typeof options.template === 'string' ||
      typeof options.render === 'function')
  )
}

export function composeExport<T0 extends {}, T1 extends {}>(
  s0: T0,
  s1: T1
): T0 & T1 {
  return Object.assign(s0, s1)
}

/**
 * 处理 vue 2.6 和 2.7 的 ref 兼容问题
 * composition-api 不支持 setup ref
 * @param refs
 * @returns
 */
export function useCompatRef(refs?: {
  [key: string]: Vue | Element | Vue[] | Element[]
}) {
  const elRef = ref(null)
  const elRefBinder = Math.random().toString(36).slice(-8)

  onMounted(() => {
    if (refs) {
      elRef.value = refs[elRefBinder]
    }
  })

  return {
    elRef,
    elRefBinder: refs ? elRefBinder : elRef,
  }
}

```

--------------------------------------------------------------------------------
/packages/next/src/editable/main.scss:
--------------------------------------------------------------------------------

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

$editable-prefix-cls: '#{$css-prefix}formily-editable';
$editable-popover-prefix-cls: '#{$css-prefix}formily-editable-popover';

.#{$editable-prefix-cls} {
  cursor: pointer;
  display: inline-flex;
  align-items: center;

  .#{$css-prefix}form-text {
    .#{$css-prefix}tag {
      transition: none !important;
    }

    .#{$css-prefix}tag:last-child {
      margin-right: 0 !important;
    }
  }

  &-content {
    display: flex;
    align-items: center;

    > * {
      margin-right: 3px;

      &:last-child {
        margin-right: 0;
      }
    }
  }

  .#{$editable-prefix-cls}-edit-btn,
  .#{$editable-prefix-cls}-close-btn {
    transition: all 0.25s ease-in-out;
    color: #aaa;
    font-size: 12px;

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

  .#{$css-prefix}form-text {
    display: flex;
    align-items: center;
  }

  .#{$editable-prefix-cls}-preview {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    word-break: break-all;
    max-width: 100px;
    display: block;
  }
}

.#{$editable-prefix-cls} {
  &-trigger {
    cursor: pointer;
    display: inline-flex !important;
    outline: none;
  }

  &-edit-btn {
    color: #aaa;
  }
}

```

--------------------------------------------------------------------------------
/packages/benchmark/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/benchmark",
  "version": "2.3.7",
  "license": "MIT",
  "private": true,
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "start": "webpack-dev-server --config webpack.dev.ts"
  },
  "devDependencies": {
    "css-loader": "^5.0.0",
    "file-loader": "^5.0.2",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^1.6.0",
    "postcss": "^8.4.31",
    "postcss-less": "^4.0.0",
    "postcss-loader": "^3.x",
    "raw-loader": "^4.0.0",
    "style-loader": "^1.1.3",
    "ts-loader": "^7.0.4",
    "webpack": "^4.41.5",
    "webpack-bundle-analyzer": "^3.9.0",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1"
  },
  "resolutions": {
    "react": "next",
    "react-dom": "next",
    "react-is": "next"
  },
  "dependencies": {
    "@formily/reactive": "2.3.7",
    "@formily/reactive-react": "2.3.7",
    "react": "next",
    "react-dom": "next",
    "react-is": "next"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

--------------------------------------------------------------------------------
/devtools/chrome-extension/src/extension/devpanel.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { useEffect, useState } from 'react'
import ReactDOM from 'react-dom'
import App from '../app'

const backgroundPageConnection = chrome.runtime.connect({
  name: '@formily-devtools-panel-script',
})

backgroundPageConnection.postMessage({
  name: 'init',
  tabId: chrome.devtools.inspectedWindow.tabId,
})

chrome.devtools.inspectedWindow.eval(
  'window.__FORMILY_DEV_TOOLS_HOOK__.openDevtools()'
)

const Devtools = () => {
  const [state, setState] = useState([])
  useEffect(() => {
    let store = {}
    const update = () => {
      setState(
        Object.keys(store).map((key) => {
          return store[key]
        })
      )
    }
    chrome.devtools.inspectedWindow.eval(
      'window.__FORMILY_DEV_TOOLS_HOOK__.update()'
    )
    backgroundPageConnection.onMessage.addListener(({ type, id, graph }) => {
      if (type === 'init') {
        store = {}
        chrome.devtools.inspectedWindow.eval(
          'window.__FORMILY_DEV_TOOLS_HOOK__.openDevtools()'
        )
      } else if (type !== 'uninstall') {
        store[id] = JSON.parse(graph)
      } else {
        delete store[id]
      }
      update()
    })
  }, [])
  return <App dataSource={state} />
}

ReactDOM.render(<Devtools />, document.getElementById('root'))

```

--------------------------------------------------------------------------------
/packages/reactive/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/reactive",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "module": "esm",
  "umd:main": "dist/formily.reactive.umd.production.js",
  "unpkg": "dist/formily.reactive.umd.production.js",
  "jsdelivr": "dist/formily.reactive.umd.production.js",
  "jsnext:main": "esm",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "start": "dumi dev",
    "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config",
    "build:docs": "dumi build",
    "benchmark": "ts-node ./benchmark"
  },
  "devDependencies": {
    "@vue/reactivity": "^3.0.11",
    "benny": "^3.6.15",
    "dumi": "^1.1.0-rc.8",
    "lodash": "^4.17.21",
    "mobx": "^6.3.0"
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

--------------------------------------------------------------------------------
/packages/reactive/src/annotations/ref.ts:
--------------------------------------------------------------------------------

```typescript
import { ObModelSymbol } from '../environment'
import { createAnnotation } from '../internals'
import { buildDataTree } from '../tree'
import {
  bindTargetKeyWithCurrentReaction,
  runReactionsFromTargetKey,
} from '../reaction'

export interface IRef {
  <T>(target: T): { value: T }
}

export const ref: IRef = createAnnotation(({ target, key, value }) => {
  const store = {
    value: target ? target[key] : value,
  }

  const proxy = {}

  const context = target ? target : store
  const property = target ? key : 'value'

  function get() {
    bindTargetKeyWithCurrentReaction({
      target: context,
      key: property,
      type: 'get',
    })
    return store.value
  }

  function set(value: any) {
    const oldValue = store.value
    store.value = value
    if (oldValue !== value) {
      runReactionsFromTargetKey({
        target: context,
        key: property,
        type: 'set',
        oldValue,
        value,
      })
    }
  }
  if (target) {
    Object.defineProperty(target, key, {
      get,
      set,
      enumerable: true,
    })
    return target
  } else {
    Object.defineProperty(proxy, 'value', {
      set,
      get,
    })
    buildDataTree(target, key, store)
    proxy[ObModelSymbol] = store
  }
  return proxy
})

```

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

```typescript
import { createForm } from '../'
import { isVoidField } from '../shared/checkers'
import { attach } from './shared'

test('getGraph/setGraph', () => {
  const form = attach(createForm())
  attach(
    form.createField({
      name: 'normal',
    })
  )
  attach(
    form.createArrayField({
      name: 'array',
    })
  )
  attach(
    form.createObjectField({
      name: 'object',
    })
  )
  attach(
    form.createVoidField({
      name: 'void',
    })
  )
  form.query('normal').take((field) => {
    if (isVoidField(field)) return
    field.selfErrors = ['error']
  })
  const graph = form.getFormGraph()
  form.clearFormGraph()
  form.setFormGraph(graph)
  const graph2 = form.getFormGraph()
  expect(graph).toEqual(graph2)
  form.setFormGraph({
    object: {
      value: 123,
    },
  })
  expect(form.query('object').get('value')).toEqual(123)
})

test('clearFormGraph', () => {
  const form = attach(createForm())
  attach(
    form.createField({
      name: 'normal',
    })
  )
  attach(
    form.createArrayField({
      name: 'array',
    })
  )
  attach(
    form.createObjectField({
      name: 'object',
    })
  )
  form.clearFormGraph('normal')
  expect(form.fields['normal']).toBeUndefined()
  expect(form.fields['array']).not.toBeUndefined()
})

```

--------------------------------------------------------------------------------
/packages/element/src/el-form/index.ts:
--------------------------------------------------------------------------------

```typescript
import { Form } from '@formily/core'
import { FormProvider as _FormProvider, createForm } from '@formily/vue'
import type { Form as _ElFormProps } from 'element-ui'
import type { FunctionalComponentOptions, Component } from 'vue'
import { Form as ElFormComponent } from 'element-ui'

const FormProvider = _FormProvider as unknown as Component

export type ElFormProps = _ElFormProps & {
  form?: Form
  component: Component
  onAutoSubmit?: (values: any) => any
}

export const ElForm: FunctionalComponentOptions<ElFormProps> = {
  functional: true,
  render(h, context) {
    const {
      form = createForm({}),
      component = ElFormComponent,
      onAutoSubmit = context.listeners?.autoSubmit,
      ...props
    } = context.props
    const submitHandler = (
      Array.isArray(onAutoSubmit) ? onAutoSubmit[0] : onAutoSubmit
    ) as (values: any) => any
    return h(FormProvider, { props: { form } }, [
      h(
        component,
        {
          ...context.data,
          props,
          nativeOn: {
            submit: (e: Event) => {
              e?.stopPropagation?.()
              e?.preventDefault?.()
              form.submit(submitHandler)
            },
          },
        },
        context.children
      ),
    ])
  },
}

export default ElForm

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField>
      <SchemaObjectField
        name="custom"
        x-component="Custom"
        :x-component-props="{
          schema: {
            type: 'object',
            properties: {
              input: {
                type: 'string',
                'x-component': 'Custom',
              },
            },
          },
        }"
      />
    </SchemaField>
  </FormProvider>
</template>

<script>
import { defineComponent, h } from '@vue/composition-api'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField, useFieldSchema } from '@formily/vue'
import 'ant-design-vue/dist/antd.css'

const Custom = defineComponent({
  setup() {
    const schemaRef = useFieldSchema()
    return () => {
      const schema = schemaRef.value
      return h(
        'div',
        {
          style: { whiteSpace: 'pre' },
        },
        [JSON.stringify(schema.toJSON(), null, 4)]
      )
    }
  },
})

const { SchemaField, SchemaObjectField } = createSchemaField({
  components: {
    Custom,
  },
})

export default {
  components: { FormProvider, SchemaField, SchemaObjectField },
  data() {
    const form = createForm({ validateFirst: true })
    return {
      form,
    }
  },
}
</script>

```

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

```vue
<template>
  <Form
    :form="form"
    :label-col="6"
    :wrapper-col="10"
    @autoSubmit="log"
    @autoSubmitFailed="log"
  >
    <SchemaField>
      <SchemaStringField
        name="input"
        title="输入框"
        x-decorator="FormItem"
        x-component="Input"
        :required="true"
      />
      <SchemaStringField
        name="select"
        title="选择框"
        x-decorator="FormItem"
        x-component="Select"
        :enum="[
          {
            label: '选项1',
            value: 1,
          },
          {
            label: '选项2',
            value: 2,
          },
        ]"
        :required="true"
      />
    </SchemaField>
    <FormButtonGroup alignFormItem>
      <Submit>提交</Submit>
    </FormButtonGroup>
  </Form>
</template>

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

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

export default {
  components: { FormButtonGroup, Submit, Form, ...fields },
  data() {
    return {
      form,
    }
  },

  methods: {
    log(value) {
      console.log(value)
    },
  },
}
</script>

```

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

```typescript
import moment from 'moment'
import { connect, mapProps, mapReadPretty } from '@formily/react'
import { TimePicker2 as NextTimePicker2 } from '@alifd/next'
import {
  TimePickerProps,
  RangePickerProps,
} from '@alifd/next/types/time-picker2'
import { PreviewText } from '../preview-text'
import {
  formatMomentValue,
  momentable,
  mapSize,
  mapStatus,
} from '../__builtins__'

type ComposedTimePicker = React.FC<React.PropsWithChildren<TimePickerProps>> & {
  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>
}

const mapTimeFormat = function () {
  return (props: any) => {
    const format = props['format'] || 'HH:mm:ss'
    const onChange = props.onChange
    return {
      ...props,
      format,
      value: momentable(props.value, format),
      onChange: (value: moment.Moment | moment.Moment[]) => {
        if (onChange) {
          onChange(formatMomentValue(value, format))
        }
      },
    }
  }
}

export const TimePicker2: ComposedTimePicker = connect(
  NextTimePicker2,
  mapProps(mapTimeFormat(), mapSize, mapStatus),
  mapReadPretty(PreviewText.TimePicker2)
)

TimePicker2.RangePicker = connect(
  NextTimePicker2.RangePicker,
  mapProps(mapTimeFormat(), mapSize, mapStatus),
  mapReadPretty(PreviewText.TimeRangePicker2)
)

export default TimePicker2

```

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

```typescript
import { isFn, Subscriber, Subscription } from './checkers'
import { each } from './array'

export class Subscribable<Payload = any> {
  subscribers: {
    index?: number
    [key: number]: Subscriber<Payload>
  } = {
    index: 0,
  }

  subscription: Subscription<Payload>

  subscribe = (callback?: Subscriber<Payload>): number => {
    if (isFn(callback)) {
      const index: number = this.subscribers.index + 1
      this.subscribers[index] = callback
      this.subscribers.index++
      return index
    }
  }

  unsubscribe = (index?: number) => {
    if (this.subscribers[index]) {
      delete this.subscribers[index]
    } else if (!index) {
      this.subscribers = {
        index: 0,
      }
    }
  }

  notify = (payload?: Payload, silent?: boolean) => {
    if (this.subscription) {
      if (this.subscription && isFn(this.subscription.notify)) {
        if (this.subscription.notify.call(this, payload) === false) {
          return
        }
      }
    }
    if (silent) return
    const filter = (payload: Payload) => {
      if (this.subscription && isFn(this.subscription.filter)) {
        return this.subscription.filter.call(this, payload)
      }
      return payload
    }
    each(this.subscribers, (callback: any) => {
      if (isFn(callback)) callback(filter(payload))
    })
  }
}

```

--------------------------------------------------------------------------------
/packages/element/docs/demos/index.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Space>
      <Field
        name="price"
        title="价格"
        :initialValue="5.2"
        :decorator="[FormItem]"
        :component="[
          InputNumber,
          {
            placeholder: '请输入',
            style: {
              width: 100,
            },
          },
        ]"
      />
      <FormItem>×</FormItem>
      <Field
        name="count"
        title="数量"
        :initialValue="100"
        :decorator="[FormItem]"
        :component="[
          InputNumber,
          {
            placeholder: '请输入',
            style: {
              width: 100,
            },
          },
        ]"
      />
      <FormConsumer>
        <template #default="{ form }">
          <FormItem>
            = {{ `${form.values.price * form.values.count} 元` }}</FormItem
          >
        </template>
      </FormConsumer>
    </Space>
  </FormProvider>
</template>

<script>
import { createForm } from '@formily/core'
import { InputNumber, FormItem, Space } from '@formily/element'
import { FormProvider, FormConsumer, Field } from '@formily/vue'

const form = createForm()

export default {
  components: { FormProvider, FormConsumer, Field, FormItem, Space },
  data() {
    return {
      form,
      InputNumber,
      FormItem,
    }
  },
}
</script>

```

--------------------------------------------------------------------------------
/packages/reactive/docs/api/markObservable.md:
--------------------------------------------------------------------------------

```markdown
# markObservable

## Description

Mark any object or class prototype as being hijacked by observable. React Node and objects with toJSON/toJS methods will be automatically bypassed in @formily/reactive. In special scenarios, we may hope that the object should be hijacked, so you can use it markObservable mark

## Signature

```ts
interface markObservable<T> {
  (target: T): T
}
```

## Example

```ts
import { observable, autorun, markObservable } from '@formily/reactive'

class A {
  property = ''

  toJSON() {}
}

const a = observable(new A())

autorun(() => {
  console.log(a.property) //will not be triggered when the property changes, because there is a toJSON method in the A instance
})

a.property = 123

//--------------------------------------------

const b = observable(markObservable(new A())) //instance-level mark, only valid for the current instance

autorun(() => {
  console.log(b.property) //Can be triggered when the property changes, because it has been marked as observable
})

b.property = 123

//--------------------------------------------

markObservable(A) //Class-level mark, then all instances will take effect

const c = observable(new A())

autorun(() => {
  console.log(c.property) //Can be triggered when the property changes, because it has been marked as observable
})

c.property = 123
```

```

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

```typescript
import { isFn } from './checkers'
import { buildDataTree } from './tree'
import { observable } from './observable'
import { getObservableMaker } from './internals'
import { isObservable, isAnnotation, isSupportObservable } from './externals'
import { Annotations } from './types'
import { action } from './action'
import { ObModelSymbol } from './environment'

export function define<Target extends object = any>(
  target: Target,
  annotations?: Annotations<Target>
): Target {
  if (isObservable(target)) return target
  if (!isSupportObservable(target)) return target
  target[ObModelSymbol] = target
  buildDataTree(undefined, undefined, target)
  for (const key in annotations) {
    const annotation = annotations[key]
    if (isAnnotation(annotation)) {
      getObservableMaker(annotation)({
        target,
        key,
      })
    }
  }
  return target
}

export function model<Target extends object = any>(target: Target): Target {
  const annotations = Object.keys(target || {}).reduce((buf, key) => {
    const descriptor = Object.getOwnPropertyDescriptor(target, key)
    if (descriptor && descriptor.get) {
      buf[key] = observable.computed
    } else if (isFn(target[key])) {
      buf[key] = action
    } else {
      buf[key] = observable
    }
    return buf
  }, {})
  return define(target, annotations)
}

```

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

```typescript
import { FormPath } from '@formily/shared'
import { Form } from '../models'
import { IFormProps } from '../types'
import {
  getValidateLocaleIOSCode,
  getLocaleByPath,
  setValidateLanguage,
  registerValidateFormats,
  registerValidateLocale,
  registerValidateMessageTemplateEngine,
  registerValidateRules,
} from '@formily/validator'
import {
  createEffectHook,
  createEffectContext,
  useEffectForm,
} from './effective'
import {
  isArrayField,
  isArrayFieldState,
  isDataField,
  isDataFieldState,
  isField,
  isFieldState,
  isForm,
  isFormState,
  isGeneralField,
  isGeneralFieldState,
  isObjectField,
  isObjectFieldState,
  isQuery,
  isVoidField,
  isVoidFieldState,
} from './checkers'

const createForm = <T extends object = any>(options?: IFormProps<T>) => {
  return new Form(options)
}

export {
  FormPath,
  createForm,
  isArrayField,
  isArrayFieldState,
  isDataField,
  isDataFieldState,
  isField,
  isFieldState,
  isForm,
  isFormState,
  isGeneralField,
  isGeneralFieldState,
  isObjectField,
  isObjectFieldState,
  isQuery,
  isVoidField,
  isVoidFieldState,
  getValidateLocaleIOSCode,
  getLocaleByPath,
  setValidateLanguage,
  registerValidateFormats,
  registerValidateLocale,
  registerValidateMessageTemplateEngine,
  registerValidateRules,
  createEffectHook,
  createEffectContext,
  useEffectForm,
}

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/shared/map-read-pretty.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <Form layout="vertical">
      <Field
        name="name"
        title="Name"
        required
        initialValue="Hello world"
        :decorator="[FormItem]"
        :component="[Input, { placeholder: 'Please Input' }]"
      />
    </Form>
  </FormProvider>
</template>

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

setValidateLanguage('en')

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

const Input = connect(
  AntdInput,
  mapReadPretty({
    props: ['value'],
    // you need import "h" from "vue" in vue3
    render(h) {
      return h('div', [this.value])
    },
  })
)

export default {
  components: {
    FormProvider,
    Field,
    Form,
  },
  data() {
    const form = createForm({ validateFirst: true, readPretty: true })
    return {
      FormItem,
      Input,
      form,
    }
  },
}
</script>

```

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

```vue
<template>
  <FormProvider :form="form">
    <SchemaField :schema="schema" />
  </FormProvider>
</template>

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

const schema = {
  type: 'object',
  properties: {
    layout: {
      type: 'void',
      'x-component': 'FormLayout',
      'x-component-props': {
        labelCol: 6,
        wrapperCol: 10,
        layout: 'vertical',
      },
      properties: {
        input: {
          type: 'string',
          title: '输入框',
          required: true,
          'x-decorator': 'FormItem',
          'x-decorator-props': {
            tooltip: '123',
          },
          'x-component': 'Input',
        },
        select: {
          type: 'string',
          title: '选择框',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Select',
        },
      },
    },
  },
}

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

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

```

--------------------------------------------------------------------------------
/packages/react/src/__tests__/form.spec.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react'
import { render } from '@testing-library/react'
import { createForm } from '@formily/core'
import { FormProvider, ObjectField, VoidField, Field } from '../'
import { FormConsumer } from '../components'
import { useParentForm } from '../hooks'

test('render form', () => {
  const form = createForm()
  render(
    <FormProvider form={form}>
      <FormConsumer>{(form) => `${form.mounted}`}</FormConsumer>
      <FormConsumer />
    </FormProvider>
  )
  expect(form.mounted).toBeTruthy()
})

const DisplayParentForm: React.FC<
  React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>
> = (props) => {
  return <div {...props}>{useParentForm()?.displayName}</div>
}

test('useParentForm', () => {
  const form = createForm()
  const { queryByTestId } = render(
    <FormProvider form={form}>
      <ObjectField name="aa">
        <Field name="bb">
          <DisplayParentForm data-testid="111" />
        </Field>
      </ObjectField>
      <VoidField name="cc">
        <Field name="dd">
          <DisplayParentForm data-testid="222" />
        </Field>
      </VoidField>
      <DisplayParentForm data-testid="333" />
    </FormProvider>
  )

  expect(queryByTestId('111').textContent).toBe('ObjectField')
  expect(queryByTestId('222').textContent).toBe('Form')
  expect(queryByTestId('333').textContent).toBe('Form')
})

```

--------------------------------------------------------------------------------
/packages/reactive-react/src/observer.ts:
--------------------------------------------------------------------------------

```typescript
import React, { forwardRef, memo, Fragment } from 'react'
import hoistNonReactStatics from 'hoist-non-react-statics'
import { useObserver } from './hooks/useObserver'
import { IObserverOptions, IObserverProps, ReactFC } from './types'

export function observer<
  P,
  Options extends IObserverOptions = IObserverOptions
>(
  component: ReactFC<P>,
  options?: Options
): React.MemoExoticComponent<
  ReactFC<
    Options extends { forwardRef: true }
      ? P & {
          ref?: 'ref' extends keyof P ? P['ref'] : React.RefAttributes<any>
        }
      : React.PropsWithoutRef<P>
  >
> {
  const realOptions = {
    forwardRef: false,
    ...options,
  }

  const wrappedComponent = realOptions.forwardRef
    ? forwardRef((props: any, ref: any) => {
        return useObserver(() => component({ ...props, ref }), realOptions)
      })
    : (props: any) => {
        return useObserver(() => component(props), realOptions)
      }

  const memoComponent = memo(wrappedComponent)

  hoistNonReactStatics(memoComponent, component)

  if (realOptions.displayName) {
    memoComponent.displayName = realOptions.displayName
  }

  return memoComponent
}

export const Observer = observer((props: IObserverProps) => {
  const children =
    typeof props.children === 'function' ? props.children() : props.children
  return React.createElement(Fragment, {}, children)
})

```

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

```typescript
import { isVue2, h as _h } from 'vue-demi'
import ReactiveField from './ReactiveField'
import { getRawComponent } from '../utils/getRawComponent'

import type { IFieldProps, DefineComponent } from '../types'
import { getFieldProps } from '../utils/getFieldProps'

let Field: DefineComponent<IFieldProps>

/* istanbul ignore else */
if (isVue2) {
  Field = {
    functional: true,
    name: 'Field',
    props: getFieldProps(),
    render(h, context) {
      const props = context.props as IFieldProps
      const attrs = context.data.attrs
      const componentData = {
        ...context.data,
        props: {
          fieldType: 'Field',
          fieldProps: {
            ...attrs,
            ...props,
            ...getRawComponent(props),
          },
        },
      }
      return _h(ReactiveField, componentData, context.children)
    },
  } as unknown as DefineComponent<IFieldProps>
} else {
  Field = {
    name: 'Field',
    props: getFieldProps(),
    setup(props: IFieldProps, context) {
      return () => {
        const componentData = {
          fieldType: 'Field',
          fieldProps: {
            ...props,
            ...getRawComponent(props),
          },
        } as Record<string, unknown>
        return _h(ReactiveField, componentData, context.slots)
      }
    },
  } as unknown as DefineComponent<IFieldProps>
}

export default Field

```

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

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

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

.#{$array-base-prefix-cls}-remove,
.#{$array-base-prefix-cls}-copy {
  transition: all 0.25s ease-in-out;
  color: $color-text1-3;
  font-size: 16px;

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

  &-disabled {
    color: $color-text1-1;
    cursor: not-allowed !important;
    &:hover {
      color: $color-text1-1;
    }
  }

  .#{$css-prefix}formily-icon {
    font-size: 16px;
  }
}

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

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

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

  &-disabled {
    color: $color-text1-1;
    cursor: not-allowed !important;
    &:hover {
      color: $color-text1-1;
    }
  }

  .#{$css-prefix}formily-icon {
    font-size: 16px;
  }
}

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

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

  &-disabled {
    color: $color-text1-1;
    cursor: not-allowed !important;
    &:hover {
      color: $color-text1-1;
    }
  }

  .#{$css-prefix}formily-icon {
    font-size: 16px;
  }
}

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

```

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

```typescript
import { isFn, isStr, each } from '@formily/shared'
import { LifeCycleHandler, LifeCyclePayload } from '../types'

type LifeCycleParams<Payload> = Array<
  | string
  | LifeCycleHandler<Payload>
  | { [key: string]: LifeCycleHandler<Payload> }
>
export class LifeCycle<Payload = any> {
  private listener: LifeCyclePayload<Payload>

  constructor(...params: LifeCycleParams<Payload>) {
    this.listener = this.buildListener(params)
  }
  buildListener = (params: any[]) => {
    return function (payload: { type: string; payload: Payload }, ctx: any) {
      for (let index = 0; index < params.length; index++) {
        let item = params[index]
        if (isFn(item)) {
          item.call(this, payload, ctx)
        } else if (isStr(item) && isFn(params[index + 1])) {
          if (item === payload.type) {
            params[index + 1].call(this, payload.payload, ctx)
          }
          index++
        } else {
          each<any, any>(item, (handler, type) => {
            if (isFn(handler) && isStr(type)) {
              if (type === payload.type) {
                handler.call(this, payload.payload, ctx)
                return false
              }
            }
          })
        }
      }
    }
  }

  notify = <Payload>(type: any, payload?: Payload, ctx?: any) => {
    if (isStr(type)) {
      this.listener.call(ctx, { type, payload }, ctx)
    }
  }
}

```

--------------------------------------------------------------------------------
/packages/path/src/__tests__/share.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { isAssignable, isEqual } from '../shared'

test('isAssignable', () => {
  expect(isAssignable({})).toBeTruthy()
  expect(isAssignable(() => {})).toBeTruthy()

  expect(isAssignable(1)).toBeFalsy()
  expect(isAssignable('str')).toBeFalsy()
})

test('isEqual', () => {
  const sameObj = {}
  const sameArray = []
  expect(isEqual('string', 'string')).toBeTruthy()
  expect(isEqual(123, 123)).toBeTruthy()
  expect(isEqual(undefined, undefined)).toBeTruthy()
  expect(isEqual(null, null)).toBeTruthy()

  expect(isEqual(sameObj, sameObj)).toBeTruthy()
  expect(isEqual(sameArray, sameArray)).toBeTruthy()

  expect(isEqual([1, '123'], [1, '123'])).toBeTruthy()
  expect(
    isEqual([1, '123', { a: 1, b: 2 }], [1, '123', { a: 1, b: 2 }])
  ).toBeTruthy()
  expect(
    isEqual([1, '123', { a: 1, b: 2 }], [1, '123', { a: 1, b: 3 }])
  ).toBeFalsy()
  expect(isEqual([1, '123'], [1, '234'])).toBeFalsy()
  expect(isEqual([], [1])).toBeFalsy()
  expect(isEqual([], {})).toBeFalsy()

  expect(isEqual({ a: [1, 2, 3] }, { a: [1, 2, 3] })).toBeTruthy()
  expect(isEqual({ a: [1, 2, 3] }, { a: [1, 2, 4] })).toBeFalsy()
  expect(isEqual({ a: 1 }, { a: 11 })).toBeFalsy()
  expect(isEqual({ a: 1 }, { a: 1, b: 2 })).toBeFalsy()

  const b = { age: '234' }
  // @ts-ignore
  Object.prototype.name = '123'
  expect(isEqual({ name: '123' }, b)).toBeFalsy()

  expect(isEqual(NaN, NaN)).toBeTruthy()
})

```

--------------------------------------------------------------------------------
/packages/reactive-vue/src/hooks/useObserver.ts:
--------------------------------------------------------------------------------

```typescript
import { Tracker } from '@formily/reactive'
import { getCurrentInstance, onBeforeUnmount, isVue3 } from 'vue-demi'
import { IObserverOptions } from '../types'

/* istanbul ignore next */
export const useObserver = (options?: IObserverOptions) => {
  if (isVue3) {
    const vm = getCurrentInstance()
    let tracker: Tracker = null
    const disposeTracker = () => {
      if (tracker) {
        tracker.dispose()
        tracker = null
      }
    }
    const vmUpdate = () => {
      vm?.proxy?.$forceUpdate()
    }

    onBeforeUnmount(disposeTracker)

    Object.defineProperty(vm, 'effect', {
      get() {
        // https://github.com/alibaba/formily/issues/2655
        return vm['_updateEffect'] || {}
      },
      set(newValue) {
        vm['_updateEffectRun'] = newValue.run
        disposeTracker()
        const newTracker = () => {
          tracker = new Tracker(() => {
            if (options?.scheduler && typeof options.scheduler === 'function') {
              options.scheduler(vmUpdate)
            } else {
              vmUpdate()
            }
          })
        }

        const update = function () {
          let refn = null
          tracker?.track(() => {
            refn = vm['_updateEffectRun'].call(newValue)
          })
          return refn
        }
        newTracker()
        newValue.run = update
        vm['_updateEffect'] = newValue
      },
    })
  }
}

```

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

```typescript
import { Heart, LifeCycle } from '../models'

test('buildLifecycles', () => {
  const heart = new Heart({
    lifecycles: [{} as any, [{}], 123],
  })
  expect(heart.lifecycles.length).toEqual(0)
})

test('clear heart', () => {
  const handler = jest.fn()
  const heart = new Heart({
    lifecycles: [new LifeCycle('event', handler)],
  })
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
  heart.clear()
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
  heart.publish({})
})

test('set lifecycles', () => {
  const handler = jest.fn()
  const heart = new Heart()
  heart.setLifeCycles([new LifeCycle('event', handler)])
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
  heart.setLifeCycles()
})

test('add/remove lifecycle', () => {
  const handler = jest.fn()
  const heart = new Heart()
  heart.addLifeCycles('xxx', [new LifeCycle('event', handler)])
  heart.addLifeCycles('yyy')
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
  heart.removeLifeCycles('xxx')
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
})

test('add/clear lifecycle', () => {
  const handler = jest.fn()
  const heart = new Heart()
  heart.addLifeCycles('xxx', [new LifeCycle('event', handler)])
  heart.addLifeCycles('yyy')
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
  heart.clear()
  heart.publish('event')
  expect(handler).toBeCalledTimes(1)
})

```

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

```typescript
export const toArray = (value: any) => {
  return Array.isArray(value)
    ? value
    : value !== undefined && value !== null
    ? [value]
    : []
}

export class ArraySet<T> {
  value: T[]
  forEachIndex = 0
  constructor(value: T[] = []) {
    this.value = value
  }

  add(item: T) {
    if (!this.has(item)) {
      this.value.push(item)
    }
  }

  has(item: T) {
    return this.value.indexOf(item) > -1
  }

  delete(item: T) {
    const len = this.value.length
    if (len === 0) return
    if (len === 1 && this.value[0] === item) {
      this.value = []
      return
    }
    const findIndex = this.value.indexOf(item)
    if (findIndex > -1) {
      this.value.splice(findIndex, 1)
      if (findIndex <= this.forEachIndex) {
        this.forEachIndex -= 1
      }
    }
  }

  forEach(callback: (value: T) => void) {
    if (this.value.length === 0) return
    this.forEachIndex = 0
    for (; this.forEachIndex < this.value.length; this.forEachIndex++) {
      callback(this.value[this.forEachIndex])
    }
  }

  batchDelete(callback: (value: T) => void) {
    if (this.value.length === 0) return
    this.forEachIndex = 0
    for (; this.forEachIndex < this.value.length; this.forEachIndex++) {
      const value = this.value[this.forEachIndex]
      this.value.splice(this.forEachIndex, 1)
      this.forEachIndex--
      callback(value)
    }
  }

  clear() {
    this.value.length = 0
  }
}

```

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

```typescript
import { traverse, traverseSchema } from '../shared'
import { FormPath } from '@formily/shared'

test('traverseSchema', () => {
  const visited = []
  const omitted = []
  traverseSchema(
    {
      type: 'string',
      title: '{{aa}}',
      required: true,
      'x-validator': 'phone',
      'x-compile-omitted': ['title'],
      default: {
        input: 123,
      },
    },
    (value, path, omitCompile) => {
      if (omitCompile) {
        omitted.push(value)
      } else {
        visited.push(path)
      }
    }
  )
  expect(visited).toEqual([
    ['x-validator'],
    ['type'],
    ['required'],
    ['default'],
  ])
  expect(omitted).toEqual(['{{aa}}'])
})

test('traverse circular reference', () => {
  // eslint-disable-next-line
  var a = {
    dd: {
      mm: null,
    },
    bb: {
      cc: {
        dd: 123,
      },
    },
    kk: {
      toJS() {},
    },
  }
  a.dd.mm = a
  traverse(a, () => {})
  traverseSchema(a as any, () => {})
})

test('traverse none circular reference', () => {
  // eslint-disable-next-line
  var dd = {
    mm: null,
  }
  let a = {
    dd,
    bb: {
      dd,
    },
  }
  const paths = []
  traverse(a, (value, path) => {
    paths.push(path)
  })
  traverseSchema(a, () => {})
  expect(
    paths.some((path) => FormPath.parse(path).includes('dd.mm'))
  ).toBeTruthy()
  expect(
    paths.some((path) => FormPath.parse(path).includes('bb.dd.mm'))
  ).toBeTruthy()
})

```

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

```typescript
import { observable } from '../'
import { contains } from '../externals'

test('array mutation', () => {
  const arr = observable([1, 2, 3, 4])
  arr.splice(2, 1)
  expect(arr).toEqual([1, 2, 4])
})

test('observable contains', () => {
  const subElement = { cc: 333 }
  const element = { aa: subElement }
  const arr = observable<any[]>([element, 2, 3, 4])
  expect(contains(arr, arr[0])).toBe(true)
  expect(contains(arr, arr[0].aa)).toBe(true)
  expect(contains(arr, element)).toBe(true)
  expect(contains(arr, subElement)).toBe(true)
  expect(contains(element, subElement)).toBe(true)
  expect(contains(element, arr[0].aa)).toBe(true)
  expect(contains(arr[0], subElement)).toBe(true)

  const obj = observable<any>({})
  const other = { bb: 321 }
  expect(contains(obj, obj.other)).toBe(false)
  obj.other = other
  obj.arr = arr

  expect(contains(obj, obj.other)).toBe(true)
  expect(contains(obj, other)).toBe(true)

  expect(contains(obj, obj.arr)).toBe(true)
  expect(contains(obj, arr)).toBe(true)
})

test('observable __proto__', () => {
  const observableArr = observable([] as any[])
  // @ts-ignore
  observableArr.__proto__ = Object.create(Array.prototype)
  observableArr[0] = {}
  expect(observableArr).toEqual([{}])

  const observableObj = observable({} as any)
  // @ts-ignore
  observableObj.__proto__ = Object.create(Object.prototype)
  observableObj.aa = {}
  expect(observableObj).toEqual({ aa: {} })
})

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/components/object-field.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <ObjectField name="object">
      <template #default="{ field }">
        <div
          v-for="key in Object.keys(field.value || {})"
          :key="key"
          :style="{ marginBottom: '10px' }"
        >
          <Space>
            <Field :name="key" :component="[Input, { placeholder: key }]" />
            <Button @click="field.removeProperty(key)"> Remove </Button>
          </Space>
        </div>
        <Space>
          <Field
            name="propertyName"
            basePath=""
            required
            :component="[Input, { placeholder: 'Property Name' }]"
          />
          <Button @click="addPropertyToField(field)"> Add </Button>
        </Space>
      </template>
    </ObjectField>
  </FormProvider>
</template>

<script>
import { Input, Space, Button } from 'ant-design-vue'
import { createForm } from '@formily/core'
import { FormProvider, ObjectField, Field } from '@formily/vue'
import 'ant-design-vue/dist/antd.css'

export default {
  components: { FormProvider, ObjectField, Field, Space, Button },
  data() {
    return {
      Input,
      form: createForm(),
    }
  },
  methods: {
    addPropertyToField(field) {
      const name = this.form.values.propertyName
      if (name && !this.form.existValuesIn(`object.${name}`)) {
        field.addProperty(name, '')
        this.form.deleteValuesIn('propertyName')
      }
    },
  },
}
</script>

```

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

```typescript
import { isVue2, h as _h } from 'vue-demi'
import ReactiveField from './ReactiveField'
import { getRawComponent } from '../utils/getRawComponent'

import type { IVoidFieldProps, DefineComponent } from '../types'
import { getVoidFieldProps } from '../utils/getFieldProps'

let VoidField: DefineComponent<IVoidFieldProps>

/* istanbul ignore else */
if (isVue2) {
  VoidField = {
    functional: true,
    name: 'VoidField',
    props: getVoidFieldProps(),
    render(h, context) {
      const props = context.props as IVoidFieldProps
      const attrs = context.data.attrs
      const componentData = {
        ...context.data,
        props: {
          fieldType: 'VoidField',
          fieldProps: {
            ...attrs,
            ...props,
            ...getRawComponent(props),
          },
        },
      }
      return _h(ReactiveField, componentData, context.children)
    },
  } as unknown as DefineComponent<IVoidFieldProps>
} else {
  VoidField = {
    name: 'VoidField',
    props: getVoidFieldProps(),
    setup(props: IVoidFieldProps, context) {
      return () => {
        const componentData = {
          fieldType: 'VoidField',
          fieldProps: {
            ...props,
            ...getRawComponent(props),
          },
        } as Record<string, unknown>
        return _h(ReactiveField, componentData, context.slots)
      }
    },
  } as unknown as DefineComponent<IVoidFieldProps>
}

export default VoidField

```

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

```typescript
import { isVue2, h as _h } from 'vue-demi'
import ReactiveField from './ReactiveField'
import { getRawComponent } from '../utils/getRawComponent'

import type { IArrayFieldProps, DefineComponent } from '../types'
import { getFieldProps } from '../utils/getFieldProps'

let ArrayField: DefineComponent<IArrayFieldProps>

/* istanbul ignore else */
if (isVue2) {
  ArrayField = {
    functional: true,
    name: 'ArrayField',
    props: getFieldProps(),
    render(h, context) {
      const props = context.props as IArrayFieldProps
      const attrs = context.data.attrs
      const componentData = {
        ...context.data,
        props: {
          fieldType: 'ArrayField',
          fieldProps: {
            ...attrs,
            ...props,
            ...getRawComponent(props),
          },
        },
      }
      return _h(ReactiveField, componentData, context.children)
    },
  } as unknown as DefineComponent<IArrayFieldProps>
} else {
  ArrayField = {
    name: 'ArrayField',
    props: getFieldProps(),
    setup(props: IArrayFieldProps, context) {
      return () => {
        const componentData = {
          fieldType: 'ArrayField',
          fieldProps: {
            ...props,
            ...getRawComponent(props),
          },
        } as Record<string, unknown>
        return _h(ReactiveField, componentData, context.slots)
      }
    },
  } as unknown as DefineComponent<IArrayFieldProps>
}

export default ArrayField

```

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

```typescript
import { LifeCycle } from '../models'

test('create lifecycle', () => {
  const handler1 = jest.fn()
  const lifecycle1 = new LifeCycle(handler1)
  lifecycle1.notify('event1')
  expect(handler1).toBeCalledTimes(1)
  expect(handler1).toBeCalledWith(
    {
      type: 'event1',
      payload: undefined,
    },
    undefined
  )
  lifecycle1.notify('event11', 'payload1')
  expect(handler1).toBeCalledTimes(2)
  expect(handler1).toBeCalledWith(
    {
      type: 'event11',
      payload: 'payload1',
    },
    undefined
  )
  const context: any = {}
  lifecycle1.notify('event12', 'payload11', context)
  expect(handler1).toBeCalledTimes(3)
  expect(handler1).toBeCalledWith(
    {
      type: 'event12',
      payload: 'payload11',
    },
    context
  )

  const handler2 = jest.fn()
  const lifecycle2 = new LifeCycle('event2', handler2)
  lifecycle2.notify('event1')
  expect(handler2).not.toBeCalled()
  lifecycle2.notify('event2')
  expect(handler2).toBeCalledTimes(1)

  const handler31 = jest.fn()
  const handler32 = jest.fn()
  const lifecycle3 = new LifeCycle({
    event31: handler31,
    event32: handler32,
  })
  lifecycle3.notify('event3')
  expect(handler31).not.toBeCalled()
  expect(handler32).not.toBeCalled()
  lifecycle3.notify('event31')
  expect(handler31).toBeCalledTimes(1)
  expect(handler32).not.toBeCalled()
  lifecycle3.notify('event32')
  expect(handler31).toBeCalledTimes(1)
  expect(handler32).toBeCalledTimes(1)
})

```

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

```typescript
import { isVue2, h as _h } from 'vue-demi'
import ReactiveField from './ReactiveField'
import { getRawComponent } from '../utils/getRawComponent'

import type { IObjectFieldProps, DefineComponent } from '../types'
import { getFieldProps } from '../utils/getFieldProps'

let ObjectField: DefineComponent<IObjectFieldProps>

/* istanbul ignore else */
if (isVue2) {
  ObjectField = {
    functional: true,
    name: 'ObjectField',
    props: getFieldProps(),
    render(h, context) {
      const props = context.props as IObjectFieldProps
      const attrs = context.data.attrs
      const componentData = {
        ...context.data,
        props: {
          fieldType: 'ObjectField',
          fieldProps: {
            ...attrs,
            ...props,
            ...getRawComponent(props),
          },
        },
      }
      return _h(ReactiveField, componentData, context.children)
    },
  } as unknown as DefineComponent<IObjectFieldProps>
} else {
  ObjectField = {
    name: 'ObjectField',
    props: getFieldProps(),
    setup(props: IObjectFieldProps, context) {
      return () => {
        const componentData = {
          fieldType: 'ObjectField',
          fieldProps: {
            ...props,
            ...getRawComponent(props),
          },
        } as Record<string, unknown>
        return _h(ReactiveField, componentData, context.slots)
      }
    },
  } as unknown as DefineComponent<IObjectFieldProps>
}

export default ObjectField

```

--------------------------------------------------------------------------------
/packages/reactive/docs/api/define.md:
--------------------------------------------------------------------------------

```markdown
# define

## Description

Manually define the domain model, you can specify the responsive behavior of specific attributes, or you can specify a method as batch mode

## Signature

```ts
interface define<Target extends object> {
  (
    target: Target,
    annotations?: {
      [key: string]: (...args: any[]) => any
    }
  ): Target
}
```

## Annotations

All Annotations currently supported are:

- observable/observable.deep defines deep hijacking responsive properties
- observable.box defines get/set container
- observable.computed defines calculated properties
- observable.ref defines reference hijacking responsive attributes
- observable.shallow defines shallow hijacking responsive properties
- action/batch defines the batch processing method

## Example

```ts
import { define, observable, action, autorun } from '@formily/reactive'

class DomainModel {
  deep = { aa: 1 }
  shallow = {}
  box = 0
  ref = ''

  constructor() {
    define(this, {
      deep: observable,
      shallow: observable.shallow,
      box: observable.box,
      ref: observable.ref,
      computed: observable.computed,
      action,
    })
  }

  get computed() {
    return this.deep.aa + this.box.get()
  }
  action(aa, box) {
    this.deep.aa = aa
    this.box.set(box)
  }
}

const model = new DomainModel()

autorun(() => {
  console.log(model.computed)
})

model.action(1, 2)
model.action(1, 2) //Repeat calls will not respond repeatedly
model.action(3, 4)
```

```

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

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

export const Form: React.FC<React.PropsWithChildren<FormProps>> = ({
  form,
  component = 'form',
  onAutoSubmit,
  onAutoSubmitFailed,
  previewTextPlaceholder,
  ...props
}) => {
  const top = useParentForm()
  const renderContent = (form: FormType | ObjectField) => (
    <PreviewText.Placeholder value={previewTextPlaceholder}>
      <FormLayout {...props}>
        {React.createElement(
          component,
          {
            onSubmit(e: React.FormEvent) {
              e?.stopPropagation?.()
              e?.preventDefault?.()
              form.submit(onAutoSubmit).catch(onAutoSubmitFailed)
            },
          },
          props.children
        )}
      </FormLayout>
    </PreviewText.Placeholder>
  )
  if (form)
    return <FormProvider form={form}>{renderContent(form)}</FormProvider>
  if (!top) throw new Error('must pass form instance by createForm')
  return renderContent(top)
}

export default Form

```

--------------------------------------------------------------------------------
/packages/reactive-vue/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@formily/reactive-vue",
  "version": "2.3.7",
  "license": "MIT",
  "main": "lib",
  "module": "esm",
  "umd:main": "dist/formily.reactive-vue.umd.production.js",
  "unpkg": "dist/formily.reactive-vue.umd.production.js",
  "jsdelivr": "dist/formily.reactive-vue.umd.production.js",
  "jsnext:main": "esm",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/alibaba/formily.git"
  },
  "types": "esm/index.d.ts",
  "bugs": {
    "url": "https://github.com/alibaba/formily/issues"
  },
  "homepage": "https://github.com/alibaba/formily#readme",
  "engines": {
    "npm": ">=3.0.0"
  },
  "scripts": {
    "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd",
    "build:cjs": "tsc --project tsconfig.build.json",
    "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm",
    "build:umd": "rollup --config"
  },
  "devDependencies": {
    "@vue/composition-api": "^1.0.0-rc.7",
    "@vue/test-utils": "1.0.0-beta.22",
    "core-js": "^2.4.0",
    "vue": "^2.6.12"
  },
  "dependencies": {
    "@formily/reactive": "2.3.7",
    "vue-demi": ">=0.13.6"
  },
  "peerDependencies": {
    "@vue/composition-api": "^1.0.0-beta.1",
    "vue": "^2.6.0 || >=3.0.0-rc.0"
  },
  "peerDependenciesMeta": {
    "@vue/composition-api": {
      "optional": true
    }
  },
  "publishConfig": {
    "access": "public"
  },
  "gitHead": "ac79c196ae9324889aca5e0501146f9b37b04283"
}

```

--------------------------------------------------------------------------------
/scripts/build-style/copy.ts:
--------------------------------------------------------------------------------

```typescript
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { copy, readFile, writeFile, existsSync } from 'fs-extra'
import glob from 'glob'

export type CopyBaseOptions = Record<'esStr' | 'libStr', string>

const importLibToEs = async ({
  libStr,
  esStr,
  filename,
}: CopyBaseOptions & { filename: string }) => {
  if (!existsSync(filename)) {
    return Promise.resolve()
  }

  const fileContent: string = (await readFile(filename)).toString()

  return writeFile(
    filename,
    fileContent.replace(new RegExp(libStr, 'g'), esStr)
  )
}

export const runCopy = ({
  resolveForItem,
  ...lastOpts
}: CopyBaseOptions & { resolveForItem?: (filename: string) => unknown }) => {
  return new Promise((resolve, reject) => {
    glob(`./src/**/*`, (err, files) => {
      if (err) {
        return reject(err)
      }

      const all = [] as Promise<unknown>[]

      for (let i = 0; i < files.length; i += 1) {
        const filename = files[i]

        resolveForItem?.(filename)

        if (/\.(less|scss)$/.test(filename)) {
          all.push(copy(filename, filename.replace(/src\//, 'esm/')))
          all.push(copy(filename, filename.replace(/src\//, 'lib/')))

          continue
        }

        if (/\/style.ts$/.test(filename)) {
          importLibToEs({
            ...lastOpts,
            filename: filename.replace(/src\//, 'esm/').replace(/\.ts$/, '.js'),
          })

          continue
        }
      }
    })
  })
}

```

--------------------------------------------------------------------------------
/packages/vue/src/__tests__/expression.scope.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { render } from '@testing-library/vue'
import { createForm } from '@formily/core'
import { FormProvider, ExpressionScope, createSchemaField, h } from '..'
import { defineComponent } from '@vue/composition-api'

test('expression scope', async () => {
  const Container = defineComponent({
    setup(_props, { slots }) {
      return () =>
        h(
          ExpressionScope,
          {
            props: { value: { $innerScope: 'inner scope value' } },
          },
          slots
        )
    },
  })
  const Input = defineComponent({
    props: ['text'],
    setup(props) {
      return () =>
        h(
          'div',
          { attrs: { 'data-testid': 'test-input' } },
          { default: () => props.text }
        )
    },
  })
  const SchemaField = createSchemaField({
    components: { Container, Input },
  })
  const form = createForm()
  const { getByTestId } = render({
    components: { ...SchemaField, FormProvider },
    data() {
      return { form }
    },
    template: `<FormProvider :form="form">
    <SchemaField :scope="{ $outerScope: 'outer scope value' }">
      <SchemaVoidField x-component="Container">
        <SchemaVoidField
          name="div"
          x-component="Input"
          :x-component-props='{ text: "{{$innerScope + $outerScope}}"}'
        />
      </SchemaVoidField>
    </SchemaField>
  </FormProvider>`,
  })

  expect(getByTestId('test-input').textContent).toBe(
    'inner scope valueouter scope value'
  )
})

```

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

```markdown
# context

## Description

All React Context of @formily/react is convenient for users to do more complex personalized customization. We can consume these contexts through useContext

## FormContext

#### Description

Form context, you can get the current Form instance

#### Signature

```ts
import { Form } from '@formily/core'

const FormContext = createContext<Form>(null)
```

## FieldContext

#### Description

Field context, you can get the current field instance

#### Signature

```ts
import { GeneralField } from '@formily/core'

const FieldContext = createContext<GeneralField>(null)
```

## SchemaMarkupContext

#### Description

Schema tag context, mainly used to collect Schema tags written in JSX Markup, and then convert them into standard JSON Schema

#### Signature

```ts
SchemaMarkupContext = createContext<Schema>(null)
```

## SchemaContext

#### Description

Field Schema context, mainly used to obtain the Schema information of the current field

#### Signature

```ts
const SchemaContext = createContext<Schema>(null)
```

## SchemaExpressionScopeContext

#### Description

Schema expression scope context

#### Signature

```ts
export const SchemaExpressionScopeContext = createContext<any>(null)
```

## SchemaOptionsContext

#### Description

Schema global parameter context, mainly used to obtain the parameters passed in from createSchemaField

#### Signature

```ts
const SchemaOptionsContext = createContext<ISchemaFieldFactoryOptions>(null)
```

```

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

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

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

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

```

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

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

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

export type ResetProps = IFieldResetOptions & IElButton

export const Reset = observer(
  defineComponent<ResetProps>({
    name: 'FReset',
    props: {
      forceClear: {
        type: Boolean,
        default: false,
      },
      validate: {
        type: Boolean,
        default: false,
      },
    },
    setup(props, context) {
      const formRef = useParentForm()
      const { listeners, slots } = context
      return () => {
        const form = formRef?.value
        return h(
          ElButton,
          {
            attrs: context.attrs,
            on: {
              ...listeners,
              click: (e: any) => {
                if (listeners?.click) {
                  if (listeners.click(e) === false) return
                }
                form
                  ?.reset('*', {
                    forceClear: props.forceClear,
                    validate: props.validate,
                  })
                  .then(listeners.resetValidateSuccess as (e: any) => void)
                  .catch(listeners.resetValidateFailed as (e: any) => void)
              },
            },
          },
          slots
        )
      }
    },
  })
)

export default Reset

```

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

```typescript
const toString = Object.prototype.toString
const isType =
  <T>(type: string | string[]) =>
  (obj: unknown): obj is T =>
    getType(obj) === `[object ${type}]`
export const getType = (obj: any) => toString.call(obj)
export const isFn = (val: any): val is Function => typeof val === 'function'
export const isArr = Array.isArray
export const isPlainObj = isType<object>('Object')
export const isStr = isType<string>('String')
export const isBool = isType<boolean>('Boolean')
export const isNum = isType<number>('Number')
export const isMap = (val: any): val is Map<any, any> =>
  val && val instanceof Map
export const isSet = (val: any): val is Set<any> => val && val instanceof Set
export const isWeakMap = (val: any): val is WeakMap<any, any> =>
  val && val instanceof WeakMap
export const isWeakSet = (val: any): val is WeakSet<any> =>
  val && val instanceof WeakSet
export const isNumberLike = (index: any): index is number =>
  isNum(index) || /^\d+$/.test(index)
export const isObj = (val: unknown): val is object => typeof val === 'object'
export const isRegExp = isType<RegExp>('RegExp')
export const isReactElement = (obj: any): boolean =>
  obj && obj['$$typeof'] && obj['_owner']
export const isHTMLElement = (target: any): target is EventTarget => {
  return Object.prototype.toString.call(target).indexOf('HTML') > -1
}

export type Subscriber<S> = (payload: S) => void

export interface Subscription<S> {
  notify?: (payload: S) => void | boolean
  filter?: (payload: S) => any
}

```

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

```markdown
# mapReadPretty

## Description

Because most third-party components do not support the reading state, if you want to quickly support the reading state, you can use the mapReadPretty function to map a reading state component

## Signature

```ts
interface mapReadPretty<Target extends React.FC> {
  (component: Target, readPrettyProps?: React.ComponentProps<Target>): React.FC
}
```

## Example

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

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

const Input = connect(
  AntdInput,
  mapReadPretty(({ value }) => <div>{value}</div>)
)

export default () => {
  const form = useMemo(() =>
    createForm({ validateFirst: true, readPretty: true })
  )
  return (
    <FormProvider form={form}>
      <Form layout="vertical">
        <Field
          name="name"
          title="Name"
          required
          initialValue="Hello world"
          decorator={[FormItem]}
          component={[Input, { placeholder: 'Please Input' }]}
        />
      </Form>
    </FormProvider>
  )
}
```

```

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

```markdown
# useFormEffects

## Description

Mainly inject side-effect logic into the current [Form](https://core.formilyjs.org/api/models/form) instance in the custom component to implement some more complex scenario-based components

<Alert>
Note: It is invalid to monitor onFormInit in the effects function, because the Form has already been initialized when rendering to the current component, and the effects function will only be executed once, so if you want to rely on the data of useState, please use the reference data of useRef.
</Alert>

## Signature

```ts
interface useFormEffects {
  (form: Form): void
}
```

## Example

```tsx
import React from 'react'
import { createForm, onFieldReact } from '@formily/core'
import { FormProvider, Field, useFormEffects } from '@formily/react'
import { Input, Form } from 'antd'

const form = createForm({
  effects() {
    onFieldReact('custom.aa', (field) => {
      field.value = field.query('input').get('value')
    })
  },
})

const Custom = () => {
  useFormEffects(() => {
    onFieldReact('custom.bb', (field) => {
      field.value = field.query('.aa').get('value')
    })
  })
  return (
    <div>
      <Field name="aa" decorator={[Form.Item]} component={[Input]} />
      <Field name="bb" decorator={[Form.Item]} component={[Input]} />
    </div>
  )
}

export default () => (
  <FormProvider form={form}>
    <Field name="input" decorator={[Form.Item]} component={[Input]} />
    <Field name="custom" decorator={[Form.Item]} component={[Custom]} />
  </FormProvider>
)
```

```

--------------------------------------------------------------------------------
/packages/vue/docs/demos/api/components/array-field.vue:
--------------------------------------------------------------------------------

```vue
<template>
  <FormProvider :form="form">
    <ArrayField name="array">
      <template #default="{ field }">
        <div
          v-for="(item, index) in field.value || []"
          :key="`${item.id}-${index}`"
          :style="{ marginBottom: '10px' }"
        >
          <Space>
            <Field :name="`${index}.value`" :component="[Input]" />
            <Button
              @click="
                () => {
                  field.remove(index)
                }
              "
            >
              Remove
            </Button>
            <Button
              @click="
                () => {
                  field.moveUp(index)
                }
              "
            >
              Move Up
            </Button>
            <Button
              @click="
                () => {
                  field.moveDown(index)
                }
              "
            >
              Move Down
            </Button>
          </Space>
        </div>
        <Button @click="() => field.push({ id: Date.now(), value: '' })">
          Add
        </Button>
      </template>
    </ArrayField>
  </FormProvider>
</template>

<script>
import { Input, Space, Button } from 'ant-design-vue'
import { createForm } from '@formily/core'
import { FormProvider, ArrayField, Field } from '@formily/vue'
import 'ant-design-vue/dist/antd.css'

export default {
  components: { FormProvider, ArrayField, Field, Space, Button },
  data() {
    return {
      Input,
      form: createForm(),
    }
  },
}
</script>

```

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

```typescript
import { reaction } from '@formily/reactive'
import { cleanupObjectChildren } from '../shared/internals'
import { JSXComponent, IFieldProps, FormPathPattern } from '../types'
import { Field } from './Field'
import { Form } from './Form'

export class ObjectField<
  Decorator extends JSXComponent = any,
  Component extends JSXComponent = any
> extends Field<Decorator, Component, any, Record<string, any>> {
  displayName = 'ObjectField'
  private additionalProperties: string[] = []
  constructor(
    address: FormPathPattern,
    props: IFieldProps<Decorator, Component>,
    form: Form,
    designable: boolean
  ) {
    super(address, props, form, designable)
    this.makeAutoCleanable()
  }

  protected makeAutoCleanable() {
    this.disposers.push(
      reaction(
        () => Object.keys(this.value || {}),
        (newKeys) => {
          const filterKeys = this.additionalProperties.filter(
            (key) => !newKeys.includes(key)
          )
          cleanupObjectChildren(this, filterKeys)
        }
      )
    )
  }

  addProperty = (key: string, value: any) => {
    this.form.setValuesIn(this.path.concat(key), value)
    this.additionalProperties.push(key)
    return this.onInput(this.value)
  }

  removeProperty = (key: string) => {
    this.form.deleteValuesIn(this.path.concat(key))
    this.additionalProperties.splice(this.additionalProperties.indexOf(key), 1)
    return this.onInput(this.value)
  }

  existProperty = (key: string) => {
    return this.form.existValuesIn(this.path.concat(key))
  }
}

```

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

```typescript
import { isFn, isPlainObj } from './checkers'

export const shallowClone = (values: any) => {
  if (Array.isArray(values)) {
    return values.slice(0)
  } else if (isPlainObj(values)) {
    if ('$$typeof' in values && '_owner' in values) {
      return values
    }
    if (values['_isBigNumber']) {
      return values
    }
    if (values['_isAMomentObject']) {
      return values
    }
    if (values['_isJSONSchemaObject']) {
      return values
    }
    if (isFn(values['toJS'])) {
      return values
    }
    if (isFn(values['toJSON'])) {
      return values
    }
    return {
      ...values,
    }
  } else if (typeof values === 'object') {
    return new values.constructor(values)
  }
  return values
}

export const clone = (values: any) => {
  if (Array.isArray(values)) {
    const res = []
    values.forEach((item) => {
      res.push(clone(item))
    })
    return res
  } else if (isPlainObj(values)) {
    if ('$$typeof' in values && '_owner' in values) {
      return values
    }
    if (values['_isBigNumber']) {
      return values
    }
    if (values['_isAMomentObject']) {
      return values
    }
    if (values['_isJSONSchemaObject']) {
      return values
    }
    if (isFn(values['toJS'])) {
      return values['toJS']()
    }
    if (isFn(values['toJSON'])) {
      return values['toJSON']()
    }
    const res = {}
    for (const key in values) {
      if (Object.hasOwnProperty.call(values, key)) {
        res[key] = clone(values[key])
      }
    }
    return res
  } else {
    return values
  }
}

```

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

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

```

--------------------------------------------------------------------------------
/packages/antd/src/array-base/style.less:
--------------------------------------------------------------------------------

```
@root-entry-name: 'default';
@import (reference) '~antd/es/style/themes/index.less';

@array-base-prefix-cls: ~'@{ant-prefix}-formily-array-base';

.@{array-base-prefix-cls}-remove,
.@{array-base-prefix-cls}-copy {
  transition: all 0.25s ease-in-out;
  color: @text-color;
  font-size: 14px;
  margin-left: 6px;
  padding: 0;
  border: none;
  width: auto;
  height: auto;

  &:hover {
    color: @primary-5;
  }

  &-disabled {
    color: @disabled-color;
    cursor: not-allowed !important;
    &:hover {
      color: @disabled-color;
    }
  }
}

.@{array-base-prefix-cls}-sort-handle {
  cursor: move;
  color: #888 !important;
  // overrid iconfont.less .anticon[tabindex] cursor
  &.anticon[tabindex] {
    cursor: move;
  }
}

.@{array-base-prefix-cls}-addition {
  transition: all 0.25s ease-in-out;
}

.@{array-base-prefix-cls}-move-down {
  transition: all 0.25s ease-in-out;
  color: @text-color;
  font-size: 14px;
  margin-left: 6px;
  padding: 0;
  border: none;
  width: auto;
  height: auto;

  &:hover {
    color: @primary-5;
  }

  &-disabled {
    color: @disabled-color;
    cursor: not-allowed !important;
    &:hover {
      color: @disabled-color;
    }
  }
}

.@{array-base-prefix-cls}-move-up {
  transition: all 0.25s ease-in-out;
  color: @text-color;
  font-size: 14px;
  margin-left: 6px;
  padding: 0;
  border: none;
  width: auto;
  height: auto;

  &:hover {
    color: @primary-5;
  }

  &-disabled {
    color: @disabled-color;
    cursor: not-allowed !important;
    &:hover {
      color: @disabled-color;
    }
  }
}

```

--------------------------------------------------------------------------------
/packages/antd/src/__builtins__/hooks/useClickAway.ts:
--------------------------------------------------------------------------------

```typescript
import { useRef, useEffect, MutableRefObject } from 'react'

const defaultEvent = 'click'

type EventType = MouseEvent | TouchEvent

type BasicTarget<T = HTMLElement> =
  | (() => T | null)
  | T
  | null
  | MutableRefObject<T | null | undefined>

type TargetElement = HTMLElement | Element | Document | Window

function getTargetElement(
  target?: BasicTarget<TargetElement>,
  defaultElement?: TargetElement
): TargetElement | undefined | null {
  if (!target) {
    return defaultElement
  }

  let targetElement: TargetElement | undefined | null

  if (typeof target === 'function') {
    targetElement = target()
  } else if ('current' in target) {
    targetElement = target.current
  } else {
    targetElement = target
  }

  return targetElement
}

export const useClickAway = (
  onClickAway: (event: EventType) => void,
  target: BasicTarget | BasicTarget[],
  eventName: string = defaultEvent
) => {
  const onClickAwayRef = useRef(onClickAway)
  onClickAwayRef.current = onClickAway

  useEffect(() => {
    const handler = (event: any) => {
      const targets = Array.isArray(target) ? target : [target]
      if (
        targets.some((targetItem) => {
          const targetElement = getTargetElement(targetItem) as HTMLElement
          return !targetElement || targetElement?.contains(event.target)
        })
      ) {
        return
      }
      onClickAwayRef.current(event)
    }

    document.addEventListener(eventName, handler)

    return () => {
      document.removeEventListener(eventName, handler)
    }
  }, [target, eventName])
}

```

--------------------------------------------------------------------------------
/packages/antd/src/array-items/style.less:
--------------------------------------------------------------------------------

```
@root-entry-name: 'default';
@import (reference) '~antd/es/style/themes/index.less';

@array-items-prefix-cls: ~'@{ant-prefix}-formily-array-items';

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

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

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

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

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

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

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

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

```

--------------------------------------------------------------------------------
/packages/next/src/__builtins__/hooks/useClickAway.ts:
--------------------------------------------------------------------------------

```typescript
import { useRef, useEffect, MutableRefObject } from 'react'

const defaultEvent = 'click'

type EventType = MouseEvent | TouchEvent

type BasicTarget<T = HTMLElement> =
  | (() => T | null)
  | T
  | null
  | MutableRefObject<T | null | undefined>

type TargetElement = HTMLElement | Element | Document | Window

function getTargetElement(
  target?: BasicTarget<TargetElement>,
  defaultElement?: TargetElement
): TargetElement | undefined | null {
  if (!target) {
    return defaultElement
  }

  let targetElement: TargetElement | undefined | null

  if (typeof target === 'function') {
    targetElement = target()
  } else if ('current' in target) {
    targetElement = target.current
  } else {
    targetElement = target
  }

  return targetElement
}

export const useClickAway = (
  onClickAway: (event: EventType) => void,
  target: BasicTarget | BasicTarget[],
  eventName: string = defaultEvent
) => {
  const onClickAwayRef = useRef(onClickAway)
  onClickAwayRef.current = onClickAway

  useEffect(() => {
    const handler = (event: any) => {
      const targets = Array.isArray(target) ? target : [target]
      if (
        targets.some((targetItem) => {
          const targetElement = getTargetElement(targetItem) as HTMLElement
          return !targetElement || targetElement?.contains(event.target)
        })
      ) {
        return
      }
      onClickAwayRef.current(event)
    }

    document.addEventListener(eventName, handler)

    return () => {
      document.removeEventListener(eventName, handler)
    }
  }, [target, eventName])
}

```

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

```
@-webkit-keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

.@{form-item-cls}-help-appear,
.@{form-item-cls}-help-enter {
  -webkit-animation-duration: 0.3s;
  animation-duration: 0.3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}

.@{form-item-cls}-help-appear.@{form-item-cls}-help-appear-active,
.@{form-item-cls}-help-enter.@{form-item-cls}-help-enter-active {
  -webkit-animation-name: antShowHelpIn;
  animation-name: antShowHelpIn;
  -webkit-animation-play-state: running;
  animation-play-state: running;
}

.@{form-item-cls}-help-appear,
.@{form-item-cls}-help-enter {
  opacity: 0;
}

.@{form-item-cls}-help-appear,
.@{form-item-cls}-help-enter {
  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}

@keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

@-webkit-keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

@keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

```

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

```scss
@-webkit-keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

.#{$form-item-cls}-help-appear,
.#{$form-item-cls}-help-enter {
  -webkit-animation-duration: 0.3s;
  animation-duration: 0.3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}

.#{$form-item-cls}-help-appear.#{$form-item-cls}-help-appear-active,
.#{$form-item-cls}-help-enter.#{$form-item-cls}-help-enter-active {
  -webkit-animation-name: antShowHelpIn;
  animation-name: antShowHelpIn;
  -webkit-animation-play-state: running;
  animation-play-state: running;
}

.#{$form-item-cls}-help-appear,
.#{$form-item-cls}-help-enter {
  opacity: 0;
}

.#{$form-item-cls}-help-appear,
.#{$form-item-cls}-help-enter {
  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}

@keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

@-webkit-keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

@keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

```

--------------------------------------------------------------------------------
/packages/reactive/docs/index.md:
--------------------------------------------------------------------------------

```markdown
---
title: Formily-Alibaba unified front-end form solution
order: 10
hero:
  title: Reactive Library
  desc: DDD-oriented Responsive State Management Solution
  actions:
    - text: Home Site
      link: //formilyjs.org
    - text: Document
      link: /guide
features:
  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg
    title: High Performance
    desc: Efficient update, Demand rendering
  - icon: https://img.alicdn.com/imgextra/i2/O1CN01YqmcpN1tDalwgyHBH_!!6000000005868-55-tps-800-800.svg
    title: Zero Dependencies
    desc: Cross Device,Cross Framework
  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg
    title: Smart Tips
    desc: Embrace Typescript
footer: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self
---

## Installation

```bash
$ npm install --save @formily/reactive

```

## Quick start

```tsx
/**
 * defaultShowCode: true
 */
import React from 'react'
import { observable } from '@formily/reactive'
import { observer } from '@formily/reactive-react'

const obs = observable({
  value: 'Hello world',
})

export default observer(() => {
  return (
    <div>
      <div>
        <input
          style={{
            height: 28,
            padding: '0 8px',
            border: '2px solid #888',
            borderRadius: 3,
          }}
          value={obs.value}
          onChange={(e) => {
            obs.value = e.target.value
          }}
        />
      </div>
      <div>{obs.value}</div>
    </div>
  )
})
```

```

--------------------------------------------------------------------------------
/docs/guide/scenes/VerifyCode.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { useState } from 'react'
import { Input, Button } from 'antd'

interface IVerifyCodeProps {
  value?: any
  onChange?: (value: any) => void
  readyPost?: boolean
  phoneNumber?: number
  style?: React.CSSProperties
}

export const VerifyCode: React.FC<React.PropsWithChildren<IVerifyCodeProps>> =
  ({ value, onChange, readyPost, phoneNumber, ...props }) => {
    const [lastTime, setLastTime] = useState(0)

    const counting = (time = 20) => {
      if (time < 0) return
      setLastTime(time)
      setTimeout(() => {
        counting(time - 1)
      }, 1000)
    }

    return (
      <div
        style={{ display: 'inline-flex', width: '100%', alignItems: 'center' }}
      >
        <Input
          {...props}
          style={{ marginRight: 5, ...props.style }}
          value={value}
          onChange={onChange}
        />
        <div
          style={{
            flexShrink: 0,
            color: '#999',
            width: 100,
            height: 35,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          {lastTime === 0 && (
            <Button
              disabled={!readyPost}
              block
              onClick={() => {
                if (phoneNumber) {
                  console.log(`post code by phone number ${phoneNumber}`)
                }
                counting()
              }}
            >
              发送验证码
            </Button>
          )}
          {lastTime > 0 && <span>剩余{lastTime}秒</span>}
        </div>
      </div>
    )
  }

```

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

```typescript
import React, { Fragment } from 'react'
import { createPortal } from 'react-dom'
import { observable } from '@formily/reactive'
import { Observer } from '@formily/react'
import { render as reactRender, unmount as reactUnmount } from './render'
export interface IPortalProps {
  id?: string | symbol
}

const PortalMap = observable(new Map<string | symbol, React.ReactNode>())

export const createPortalProvider = (id: string | symbol) => {
  const Portal = (props: React.PropsWithChildren<IPortalProps>) => {
    const portalId = props.id ?? id
    if (portalId && !PortalMap.has(portalId)) {
      PortalMap.set(portalId, null)
    }

    return (
      <Fragment>
        {props.children}
        <Observer>
          {() => {
            if (!portalId) return null
            const portal = PortalMap.get(portalId)
            if (portal) return createPortal(portal, document.body)
            return null
          }}
        </Observer>
      </Fragment>
    )
  }
  return Portal
}

export function createPortalRoot<T extends React.ReactNode>(
  host: HTMLElement,
  id: string
) {
  function render(renderer?: () => T) {
    if (PortalMap.has(id)) {
      PortalMap.set(id, renderer?.())
    } else if (host) {
      reactRender(<Fragment>{renderer?.()}</Fragment>, host)
    }
  }

  function unmount() {
    if (PortalMap.has(id)) {
      PortalMap.set(id, null)
    }
    if (host) {
      const unmountResult = reactUnmount(host)
      if (unmountResult && host.parentNode) {
        host.parentNode?.removeChild(host)
      }
    }
  }

  return {
    render,
    unmount,
  }
}

```

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

```typescript
import React, { Fragment } from 'react'
import { createPortal } from 'react-dom'
import { observable } from '@formily/reactive'
import { Observer } from '@formily/react'
import { render as reactRender, unmount as reactUnmount } from './render'
export interface IPortalProps {
  id?: string | symbol
}

const PortalMap = observable(new Map<string | symbol, React.ReactNode>())

export const createPortalProvider = (id: string | symbol) => {
  const Portal = (props: React.PropsWithChildren<IPortalProps>) => {
    const portalId = props.id ?? id
    if (portalId && !PortalMap.has(portalId)) {
      PortalMap.set(portalId, null)
    }

    return (
      <Fragment>
        {props.children}
        <Observer>
          {() => {
            if (!portalId) return null
            const portal = PortalMap.get(portalId)
            if (portal) return createPortal(portal, document.body)
            return null
          }}
        </Observer>
      </Fragment>
    )
  }
  return Portal
}

export function createPortalRoot<T extends React.ReactNode>(
  host: HTMLElement,
  id: string
) {
  function render(renderer?: () => T) {
    if (PortalMap.has(id)) {
      PortalMap.set(id, renderer?.())
    } else if (host) {
      reactRender(<Fragment>{renderer?.()}</Fragment>, host)
    }
  }

  function unmount() {
    if (PortalMap.has(id)) {
      PortalMap.set(id, null)
    }
    if (host) {
      const unmountResult = reactUnmount(host)
      if (unmountResult && host.parentNode) {
        host.parentNode?.removeChild(host)
      }
    }
  }

  return {
    render,
    unmount,
  }
}

```

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

```scss
@-webkit-keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

.#{$form-item-prefix}-help-appear,
.#{$form-item-prefix}-help-enter {
  -webkit-animation-duration: 0.3s;
  animation-duration: 0.3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}

.#{$form-item-prefix}-help-appear.#{$form-item-prefix}-help-appear-active,
.#{$form-item-prefix}-help-enter.#{$form-item-prefix}-help-enter-active {
  -webkit-animation-name: antShowHelpIn;
  animation-name: antShowHelpIn;
  -webkit-animation-play-state: running;
  animation-play-state: running;
}

.#{$form-item-prefix}-help-appear,
.#{$form-item-prefix}-help-enter {
  opacity: 0;
}

.#{$form-item-prefix}-help-appear,
.#{$form-item-prefix}-help-enter {
  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}

@keyframes antShowHelpIn {
  0% {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }

  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

@-webkit-keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

@keyframes antShowHelpOut {
  to {
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    opacity: 0;
  }
}

```
Page 4/35FirstPrevNextLast