#
tokens: 49791/50000 15/1152 files (page 16/35)
lines: off (toggle) GitHub
raw markdown copy
This is page 16 of 35. Use http://codebase.md/alibaba/formily?lines=false&page={x} to view the full context.

# Directory Structure

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

# Files

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

```typescript
import React from 'react'
import cls from 'classnames'
import { usePrefixCls } from './hooks/usePrefixCls'
export type IconProps = React.HTMLAttributes<SVGSVGElement> & {
  ref?: React.ForwardedRef<SVGSVGElement>
}

export type IconType = React.ForwardRefExoticComponent<IconProps>

export const Icon: IconType = React.forwardRef((props, ref) => {
  const prefix = usePrefixCls('formily-icon')
  return (
    <svg
      {...props}
      ref={ref}
      className={cls(prefix, props.className)}
      style={{
        ...props.style,
        cursor: props.onClick ? 'pointer' : '',
        display: 'inline-block',
        verticalAlign: 'middle',
      }}
      viewBox="64 64 896 896"
      fill="currentColor"
      width="1em"
      height="1em"
      focusable="false"
      aria-hidden="true"
    >
      {props.children}
    </svg>
  )
})

export const MenuOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"></path>
  </Icon>
))

export const PlusOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path>
    <path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path>
  </Icon>
))

export const UpOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"></path>
  </Icon>
))

export const DownOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path>
  </Icon>
))

export const DeleteOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"></path>
  </Icon>
))

export const CopyOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path>
  </Icon>
))

export const QuestionCircleOutlinedIcon: IconType = React.forwardRef(
  (props, ref) => (
    <Icon {...props} ref={ref}>
      <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path>
      <path d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"></path>
    </Icon>
  )
)
export const CloseCircleOutlinedIcon: IconType = React.forwardRef(
  (props, ref) => (
    <Icon {...props} ref={ref}>
      <path d="M685.4 354.8c0-4.4-3.6-8-8-8l-66 .3L512 465.6l-99.3-118.4-66.1-.3c-4.4 0-8 3.5-8 8 0 1.9.7 3.7 1.9 5.2l130.1 155L340.5 670a8.32 8.32 0 00-1.9 5.2c0 4.4 3.6 8 8 8l66.1-.3L512 564.4l99.3 118.4 66 .3c4.4 0 8-3.5 8-8 0-1.9-.7-3.7-1.9-5.2L553.5 515l130.1-155c1.2-1.4 1.8-3.3 1.8-5.2z"></path>
      <path d="M512 65C264.6 65 64 265.6 64 513s200.6 448 448 448 448-200.6 448-448S759.4 65 512 65zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path>
    </Icon>
  )
)
export const CheckCircleOutlinedIcon: IconType = React.forwardRef(
  (props, ref) => (
    <Icon {...props} ref={ref}>
      <path d="M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"></path>
      <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path>
    </Icon>
  )
)
export const ExclamationCircleOutlinedIcon: IconType = React.forwardRef(
  (props, ref) => (
    <Icon {...props} ref={ref}>
      <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path>
      <path d="M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"></path>
    </Icon>
  )
)

export const EditOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"></path>{' '}
  </Icon>
))
export const CloseOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path>
  </Icon>
))
export const MessageOutlinedIcon: IconType = React.forwardRef((props, ref) => (
  <Icon {...props} ref={ref}>
    <path d="M464 512a48 48 0 1096 0 48 48 0 10-96 0zm200 0a48 48 0 1096 0 48 48 0 10-96 0zm-400 0a48 48 0 1096 0 48 48 0 10-96 0zm661.2-173.6c-22.6-53.7-55-101.9-96.3-143.3a444.35 444.35 0 00-143.3-96.3C630.6 75.7 572.2 64 512 64h-2c-60.6.3-119.3 12.3-174.5 35.9a445.35 445.35 0 00-142 96.5c-40.9 41.3-73 89.3-95.2 142.8-23 55.4-34.6 114.3-34.3 174.9A449.4 449.4 0 00112 714v152a46 46 0 0046 46h152.1A449.4 449.4 0 00510 960h2.1c59.9 0 118-11.6 172.7-34.3a444.48 444.48 0 00142.8-95.2c41.3-40.9 73.8-88.7 96.5-142 23.6-55.2 35.6-113.9 35.9-174.5.3-60.9-11.5-120-34.8-175.6zm-151.1 438C704 845.8 611 884 512 884h-1.7c-60.3-.3-120.2-15.3-173.1-43.5l-8.4-4.5H188V695.2l-4.5-8.4C155.3 633.9 140.3 574 140 513.7c-.4-99.7 37.7-193.3 107.6-263.8 69.8-70.5 163.1-109.5 262.8-109.9h1.7c50 0 98.5 9.7 144.2 28.9 44.6 18.7 84.6 45.6 119 80 34.3 34.3 61.3 74.4 80 119 19.4 46.2 29.1 95.2 28.9 145.8-.6 99.6-39.7 192.9-110.1 262.7z"></path>
  </Icon>
))

```

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

```markdown
# FormLayout

> 区块级布局批量控制组件,借助该组件,我们可以轻松的控制被 FormLayout 圈住的所有 FormItem 组件的布局模式

## Markup Schema 案例

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Void
        x-component="FormLayout"
        x-component-props={{
          labelCol: 6,
          wrapperCol: 10,
        }}
      >
        <SchemaField.String
          name="input"
          title="输入框"
          x-decorator="FormItem"
          x-decorator-props={{
            tooltip: <div>123</div>,
          }}
          x-component="Input"
          required
        />
        <SchemaField.String
          name="select"
          title="选择框"
          x-decorator="FormItem"
          x-component="Select"
          required
        />
      </SchemaField.Void>
    </SchemaField>
  </FormProvider>
)
```

## JSON Schema 案例

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

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

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: <div>123</div>,
          },
          'x-component': 'Input',
        },
        select: {
          type: 'string',
          title: '选择框',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Select',
        },
      },
    },
  },
}

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
  </FormProvider>
)
```

## 纯 JSX 案例

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout
      breakpoints={[680]}
      layout={['vertical', 'horizontal']}
      labelAlign={['left', 'right']}
      labelCol={[24, 6]}
      wrapperCol={[24, 10]}
    >
      <Field
        name="input"
        required
        title="输入框"
        decorator={[FormItem]}
        component={[Input]}
      />
      <Field
        name="select"
        required
        title="选择框"
        decorator={[FormItem]}
        component={[Select]}
      />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>提交</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## API

| 属性名         | 类型                                                                                   | 描述                                     | 默认值     |
| -------------- | -------------------------------------------------------------------------------------- | ---------------------------------------- | ---------- |
| style          | CSSProperties                                                                          | 样式                                     | -          |
| className      | string                                                                                 | 类名                                     | -          |
| colon          | boolean                                                                                | 是否有冒号                               | true       |
| requiredMark   | boolean \| `"optional"`                                                                | 必选样式,可以切换为必选或者可选展示样式 | true       |
| labelAlign     | `'right' \| 'left' \| ('right' \| 'left')[]`                                           | 标签内容对齐                             | -          |
| wrapperAlign   | `'right' \| 'left' \| ('right' \| 'left')[]`                                           | 组件容器内容对齐                         | -          |
| labelWrap      | boolean                                                                                | 标签内容换行                             | false      |
| labelWidth     | number                                                                                 | 标签宽度(px)                             | -          |
| wrapperWidth   | number                                                                                 | 组件容器宽度(px)                         | -          |
| wrapperWrap    | boolean                                                                                | 组件容器换行                             | false      |
| labelCol       | `number \| number[]`                                                                   | 标签宽度(24 column)                      | -          |
| wrapperCol     | `number \| number[]`                                                                   | 组件容器宽度(24 column)                  | -          |
| fullness       | boolean                                                                                | 组件容器宽度 100%                        | false      |
| size           | `'small' \| 'default' \| 'large'`                                                      | 组件尺寸                                 | default    |
| layout         | `'vertical' \| 'horizontal' \| 'inline' \| ('vertical' \| 'horizontal' \| 'inline')[]` | 布局模式                                 | horizontal |
| direction      | `'rtl' \| 'ltr'`                                                                       | 方向(暂不支持)                           | ltr        |
| inset          | boolean                                                                                | 内联布局                                 | false      |
| shallow        | boolean                                                                                | 上下文浅层传递                           | true       |
| feedbackLayout | `'loose' \| 'terse' \| 'popover' \| 'none'`                                            | 反馈布局                                 | true       |
| tooltipLayout  | `"icon" \| "text"`                                                                     | 问号提示布局                             | `"icon"`   |
| tooltipIcon    | ReactNode                                                                              | 问号提示图标                             | -          |
| bordered       | boolean                                                                                | 是否有边框                               | true       |
| breakpoints    | number[]                                                                               | 容器尺寸断点                             | -          |
| gridColumnGap  | number                                                                                 | 网格布局列间距                           | 8          |
| gridRowGap     | number                                                                                 | 网格布局行间距                           | 4          |
| spaceGap       | number                                                                                 | 弹性间距                                 | 8          |

```

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

```typescript
import {
  FormPath,
  FormPathPattern,
  isValid,
  toArr,
  each,
  isFn,
} from '@formily/shared'
import {
  JSXComponent,
  LifeCycleTypes,
  FieldDisplayTypes,
  FieldPatternTypes,
  FieldDecorator,
  FieldComponent,
  IFieldActions,
} from '../types'
import {
  locateNode,
  destroy,
  initFieldUpdate,
  getArrayParent,
  getObjectParent,
} from '../shared/internals'
import { Form } from './Form'
import { Query } from './Query'

export class BaseField<Decorator = any, Component = any, TextType = any> {
  title: TextType
  description: TextType

  selfDisplay: FieldDisplayTypes
  selfPattern: FieldPatternTypes
  initialized: boolean
  mounted: boolean
  unmounted: boolean

  content: any

  data: any

  decoratorType: Decorator
  decoratorProps: Record<string, any>
  componentType: Component
  componentProps: Record<string, any>

  designable: boolean
  address: FormPath
  path: FormPath
  form: Form

  disposers: (() => void)[] = []

  actions: IFieldActions = {}

  locate(address: FormPathPattern) {
    this.form.fields[address.toString()] = this as any
    locateNode(this as any, address)
  }

  get indexes(): number[] {
    return this.path.transform(/^\d+$/, (...args) =>
      args.map((index) => Number(index))
    ) as number[]
  }

  get index() {
    return this.indexes[this.indexes.length - 1] ?? -1
  }

  get records() {
    const array = getArrayParent(this)
    return array?.value
  }

  get record() {
    const obj = getObjectParent(this)
    if (obj) {
      return obj.value
    }
    const index = this.index
    const array = getArrayParent(this, index)
    if (array) {
      return array.value?.[index]
    }
    return this.form.values
  }

  get component() {
    return [this.componentType, this.componentProps]
  }

  set component(value: FieldComponent<Component>) {
    const component = toArr(value)
    this.componentType = component[0]
    this.componentProps = component[1] || {}
  }

  get decorator() {
    return [this.decoratorType, this.decoratorProps]
  }

  set decorator(value: FieldDecorator<Decorator>) {
    const decorator = toArr(value)
    this.decoratorType = decorator[0]
    this.decoratorProps = decorator[1] || {}
  }

  get parent() {
    let parent = this.address.parent()
    let identifier = parent.toString()
    while (!this.form.fields[identifier]) {
      parent = parent.parent()
      identifier = parent.toString()
      if (!identifier) return
    }
    return this.form.fields[identifier]
  }

  get display(): FieldDisplayTypes {
    const parentDisplay = (this.parent as any)?.display
    if (parentDisplay && parentDisplay !== 'visible') {
      if (this.selfDisplay && this.selfDisplay !== 'visible')
        return this.selfDisplay
      return parentDisplay
    }
    if (isValid(this.selfDisplay)) return this.selfDisplay
    return parentDisplay || this.form.display || 'visible'
  }

  get pattern(): FieldPatternTypes {
    const parentPattern: FieldPatternTypes =
      (this.parent as any)?.pattern || this.form.pattern || 'editable'
    const selfPattern = this.selfPattern
    if (isValid(selfPattern)) {
      if (parentPattern === 'readPretty' && selfPattern !== 'editable') {
        return parentPattern
      }
      return selfPattern
    }
    return parentPattern
  }

  get editable() {
    return this.pattern === 'editable'
  }

  get disabled() {
    return this.pattern === 'disabled'
  }

  get readOnly() {
    return this.pattern === 'readOnly'
  }

  get readPretty() {
    return this.pattern === 'readPretty'
  }

  get hidden() {
    return this.display === 'hidden'
  }

  get visible() {
    return this.display === 'visible'
  }

  get destroyed() {
    return !this.form.fields[this.address.toString()]
  }

  set hidden(hidden: boolean) {
    if (!isValid(hidden)) return
    if (hidden) {
      this.display = 'hidden'
    } else {
      this.display = 'visible'
    }
  }

  set visible(visible: boolean) {
    if (!isValid(visible)) return
    if (visible) {
      this.display = 'visible'
    } else {
      this.display = 'none'
    }
  }

  set editable(editable: boolean) {
    if (!isValid(editable)) return
    if (editable) {
      this.pattern = 'editable'
    } else {
      this.pattern = 'readPretty'
    }
  }

  set readOnly(readOnly: boolean) {
    if (!isValid(readOnly)) return
    if (readOnly) {
      this.pattern = 'readOnly'
    } else {
      this.pattern = 'editable'
    }
  }

  set disabled(disabled: boolean) {
    if (!isValid(disabled)) return
    if (disabled) {
      this.pattern = 'disabled'
    } else {
      this.pattern = 'editable'
    }
  }

  set readPretty(readPretty: boolean) {
    if (!isValid(readPretty)) return
    if (readPretty) {
      this.pattern = 'readPretty'
    } else {
      this.pattern = 'editable'
    }
  }

  set pattern(pattern: FieldPatternTypes) {
    this.selfPattern = pattern
  }

  set display(display: FieldDisplayTypes) {
    this.selfDisplay = display
  }

  setTitle = (title?: TextType) => {
    this.title = title
  }

  setDescription = (description?: TextType) => {
    this.description = description
  }

  setDisplay = (type?: FieldDisplayTypes) => {
    this.display = type
  }

  setPattern = (type?: FieldPatternTypes) => {
    this.pattern = type
  }

  setComponent = <C extends JSXComponent, ComponentProps extends object = {}>(
    component?: C,
    props?: ComponentProps
  ) => {
    if (component) {
      this.componentType = component as any
    }
    if (props) {
      this.componentProps = this.componentProps || {}
      Object.assign(this.componentProps, props)
    }
  }

  setComponentProps = <ComponentProps extends object = {}>(
    props?: ComponentProps
  ) => {
    if (props) {
      this.componentProps = this.componentProps || {}
      Object.assign(this.componentProps, props)
    }
  }

  setDecorator = <D extends JSXComponent, ComponentProps extends object = {}>(
    component?: D,
    props?: ComponentProps
  ) => {
    if (component) {
      this.decoratorType = component as any
    }
    if (props) {
      this.decoratorProps = this.decoratorProps || {}
      Object.assign(this.decoratorProps, props)
    }
  }

  setDecoratorProps = <ComponentProps extends object = {}>(
    props?: ComponentProps
  ) => {
    if (props) {
      this.decoratorProps = this.decoratorProps || {}
      Object.assign(this.decoratorProps, props)
    }
  }

  setData = (data: any) => {
    this.data = data
  }

  setContent = (content: any) => {
    this.content = content
  }

  onInit = () => {
    this.initialized = true
    initFieldUpdate(this as any)
    this.notify(LifeCycleTypes.ON_FIELD_INIT)
  }

  onMount = () => {
    this.mounted = true
    this.unmounted = false
    this.notify(LifeCycleTypes.ON_FIELD_MOUNT)
  }

  onUnmount = () => {
    this.mounted = false
    this.unmounted = true
    this.notify(LifeCycleTypes.ON_FIELD_UNMOUNT)
  }

  query = (pattern: FormPathPattern | RegExp) => {
    return new Query({
      pattern,
      base: this.address,
      form: this.form,
    })
  }

  notify = (type: LifeCycleTypes, payload?: any) => {
    return this.form.notify(type, payload ?? this)
  }

  dispose = () => {
    this.disposers.forEach((dispose) => {
      dispose()
    })
    this.form.removeEffects(this)
  }

  destroy = (forceClear = true) => {
    destroy(this.form.fields, this.address.toString(), forceClear)
  }

  match = (pattern: FormPathPattern) => {
    return FormPath.parse(pattern).matchAliasGroup(this.address, this.path)
  }

  inject = (actions: IFieldActions) => {
    each(actions, (action, key) => {
      if (isFn(action)) {
        this.actions[key] = action
      }
    })
  }

  invoke = (name: string, ...args: any[]) => {
    return this.actions[name]?.(...args)
  }
}

```

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

```markdown
# FormLayout

> Block-level layout batch control component, with the help of this component, we can easily control the layout mode of all FormItem components enclosed by FormLayout

## Markup Schema example

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.Void
        x-component="FormLayout"
        x-component-props={{
          labelCol: 6,
          wrapperCol: 10,
        }}
      >
        <SchemaField.String
          name="input"
          title="input box"
          x-decorator="FormItem"
          x-decorator-props={{
            tooltip: <div>123</div>,
          }}
          x-component="Input"
          required
        />
        <SchemaField.String
          name="select"
          title="select box"
          x-decorator="FormItem"
          x-component="Select"
          required
        />
      </SchemaField.Void>
    </SchemaField>
  </FormProvider>
)
```

## JSON Schema case

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

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

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: 'input box',
          required: true,
          'x-decorator': 'FormItem',
          'x-decorator-props': {
            tooltip: <div>123</div>,
          },
          'x-component': 'Input',
        },
        select: {
          type: 'string',
          title: 'Select box',
          required: true,
          'x-decorator': 'FormItem',
          'x-component': 'Select',
        },
      },
    },
  },
}

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField schema={schema} />
  </FormProvider>
)
```

## Pure JSX case

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={10}>
      <Field
        name="input"
        required
        title="input box"
        decorator={[FormItem]}
        component={[Input]}
      />
      <Field
        name="select"
        required
        title="select box"
        decorator={[FormItem]}
        component={[Select]}
      />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>Submit</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## API

| Property name  | Type                                                                                   | Description                           | Default value |
| -------------- | -------------------------------------------------------------------------------------- | ------------------------------------- | ------------- |
| style          | CSSProperties                                                                          | Style                                 | -             |
| className      | string                                                                                 | class name                            | -             |
| colon          | boolean                                                                                | Is there a colon                      | true          |
| labelAlign     | `'right' \| 'left' \| ('right' \| 'left')[]`                                           | Label content alignment               | -             |
| wrapperAlign   | `'right' \| 'left' \| ('right' \| 'left')[]`                                           | Component container content alignment | -             |
| labelWrap      | boolean                                                                                | Wrap label content                    | false         |
| labelWidth     | number                                                                                 | Label width (px)                      | -             |
| wrapperWidth   | number                                                                                 | Component container width (px)        | -             |
| wrapperWrap    | boolean                                                                                | Component container wrap              | false         |
| labelCol       | `number \| number[]`                                                                   | Label width (24 column)               | -             |
| wrapperCol     | `number \| number[]`                                                                   | Component container width (24 column) | -             |
| fullness       | boolean                                                                                | Component container width 100%        | false         |
| size           | `'small' \|'default' \|'large'`                                                        | component size                        | default       |
| layout         | `'vertical' \| 'horizontal' \| 'inline' \| ('vertical' \| 'horizontal' \| 'inline')[]` | layout mode                           | horizontal    |
| direction      | `'rtl' \|'ltr'`                                                                        | direction (not supported yet)         | ltr           |
| inset          | boolean                                                                                | Inline layout                         | false         |
| shallow        | boolean                                                                                | shallow context transfer              | true          |
| feedbackLayout | `'loose' \|'terse' \|'popover' \|'none'`                                               | feedback layout                       | true          |
| tooltipLayout  | `"icon" \| "text"`                                                                     | Ask the prompt layout                 | `"icon"`      |
| tooltipIcon    | ReactNode                                                                              | Ask the prompt icon                   | -             |
| bordered       | boolean                                                                                | Is there a border                     | true          |
| breakpoints    | number[]                                                                               | Container size breakpoints            | -             |
| gridColumnGap  | number                                                                                 | Grid Column Gap                       | 8             |
| gridRowGap     | number                                                                                 | Grid Row Gap                          | 4             |
| spaceGap       | number                                                                                 | Space Gap                             | 8             |

```

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

```markdown
# FormButtonGroup

> Form button group layout component

## Common case

```tsx
import React from 'react'
import {
  FormButtonGroup,
  Submit,
  Reset,
  FormItem,
  Input,
  FormLayout,
} from '@formily/antd'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
const SchemaField = createSchemaField({
  components: {
    FormItem,
    Input,
  },
})

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.FormItem>
          <Submit onSubmit={console.log}>Submit</Submit>
          <Reset>Reset</Reset>
        </FormButtonGroup.FormItem>
      </FormLayout>
    </FormProvider>
  )
}
```

## Suction bottom case

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.Sticky>
          <FormButtonGroup.FormItem>
            <Submit onSubmit={console.log}>Submit</Submit>
            <Reset>Reset</Reset>
          </FormButtonGroup.FormItem>
        </FormButtonGroup.Sticky>
      </FormLayout>
    </FormProvider>
  )
}
```

## Suction bottom centering case

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.Sticky align="center">
          <FormButtonGroup>
            <Submit onSubmit={console.log}>Submit</Submit>
            <Reset>Reset</Reset>
          </FormButtonGroup>
        </FormButtonGroup.Sticky>
      </FormLayout>
    </FormProvider>
  )
}
```

## API

### FormButtonGroup

> This component is mainly used to handle the button group gap

| Property name | Type                        | Description | Default value |
| ------------- | --------------------------- | ----------- | ------------- |
| gutter        | number                      | Gap size    | 8px           |
| align         | `'left'\|'center'\|'right'` | Alignment   | `'left'`      |

### FormButtonGroup.FormItem

> This component is mainly used to deal with the alignment of the button group and the main form FormItem

Refer to [FormItem](/components/form-item) property

### FormButtonGroup.Sticky

> This component is mainly used to deal with the floating positioning problem of the button group

| Property name | Type                        | Description | Default value |
| ------------- | --------------------------- | ----------- | ------------- |
| align         | `'left'\|'center'\|'right'` | Alignment   | `'left'`      |

```

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

```markdown
# Upload

> Upload components
>
> Note: Using the upload component, it is recommended that users perform secondary packaging. Users do not need to care about the data communication between the upload component and Formily, only the style and basic upload configuration are required.

## Markup Schema example

```tsx
import React from 'react'
import {
  Upload,
  FormItem,
  FormButtonGroup,
  Submit,
  FormLayout,
} from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Button } from '@alifd/next'
import { UploadOutlined, InboxOutlined } from '@ant-design/icons'

const NormalUpload = (props) => {
  return (
    <Upload
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      headers={{
        authorization: 'authorization-text',
      }}
    >
      <Button>
        <UploadOutlined />
        upload files
      </Button>
    </Upload>
  )
}

const CardUpload = (props) => {
  return (
    <Upload.Card
      {...props}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      withCredentials={false}
      headers={{
        authorization: 'authorization-text',
      }}
    />
  )
}

const DraggerUpload = (props) => {
  return (
    <Upload.Dragger
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    >
      <div className="next-upload-drag">
        <p className="next-upload-drag-icon" style={{ fontSize: 50 }}>
          <InboxOutlined />
        </p>
        <p className="next-upload-drag-text">
          click to <Button text>download template</Button> or drag file here
        </p>
        <p className="next-upload-drag-hint">supports docx, xls, PDF </p>
      </div>
    </Upload.Dragger>
  )
}

const SchemaField = createSchemaField({
  components: {
    NormalUpload,
    CardUpload,
    DraggerUpload,
    FormItem,
  },
})

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={14}>
      <SchemaField>
        <SchemaField.Array
          name="upload"
          title="Upload"
          x-decorator="FormItem"
          x-component="NormalUpload"
          required
        />
        <SchemaField.Array
          name="upload2"
          title="Card upload"
          x-decorator="FormItem"
          x-component="CardUpload"
          required
        />
        <SchemaField.Array
          name="upload3"
          title="Drag and drop upload"
          x-decorator="FormItem"
          x-component="DraggerUpload"
          required
        />
      </SchemaField>
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>Submit</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## JSON Schema case

```tsx
import React from 'react'
import {
  Upload,
  FormItem,
  FormButtonGroup,
  Submit,
  FormLayout,
} from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Button } from '@alifd/next'
import { UploadOutlined, InboxOutlined } from '@ant-design/icons'

const NormalUpload = (props) => {
  return (
    <Upload
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      headers={{
        authorization: 'authorization-text',
      }}
    >
      <Button>
        <UploadOutlined />
        upload files
      </Button>
    </Upload>
  )
}

const CardUpload = (props) => {
  return (
    <Upload.Card
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      headers={{
        authorization: 'authorization-text',
      }}
    />
  )
}

const DraggerUpload = (props) => {
  return (
    <Upload.Dragger
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    >
      <div className="next-upload-drag">
        <p className="next-upload-drag-icon" style={{ fontSize: 50 }}>
          <InboxOutlined />
        </p>
        <p className="next-upload-drag-text">
          click to <Button text>download template</Button> or drag file here
        </p>
        <p className="next-upload-drag-hint">supports docx, xls, PDF </p>
      </div>
    </Upload.Dragger>
  )
}

const SchemaField = createSchemaField({
  components: {
    NormalUpload,
    CardUpload,
    DraggerUpload,
    FormItem,
  },
})

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    upload: {
      type: 'array',
      title: 'Upload',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'NormalUpload',
    },
    upload2: {
      type: 'array',
      title: 'Card upload',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'CardUpload',
    },
    upload3: {
      type: 'array',
      title: 'Drag and drop upload',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'DraggerUpload',
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={14}>
      <SchemaField schema={schema} />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>Submit</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## Pure JSX case

```tsx
import React from 'react'
import {
  Upload,
  FormItem,
  FormButtonGroup,
  Submit,
  FormLayout,
} from '@formily/next'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'
import { Button } from '@alifd/next'
import { UploadOutlined, InboxOutlined } from '@ant-design/icons'

const NormalUpload = (props) => {
  return (
    <Upload
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      headers={{
        authorization: 'authorization-text',
      }}
    >
      <Button>
        <UploadOutlined />
        upload files
      </Button>
    </Upload>
  )
}

const CardUpload = (props) => {
  return (
    <Upload.Card
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
      headers={{
        authorization: 'authorization-text',
      }}
    />
  )
}

const DraggerUpload = (props) => {
  return (
    <Upload.Dragger
      {...props}
      withCredentials={false}
      action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    >
      <div className="next-upload-drag">
        <p className="next-upload-drag-icon" style={{ fontSize: 50 }}>
          <InboxOutlined />
        </p>
        <p className="next-upload-drag-text">
          click to <Button text>download template</Button> or drag file here
        </p>
        <p className="next-upload-drag-hint">supports docx, xls, PDF </p>
      </div>
    </Upload.Dragger>
  )
}

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={14}>
      <Field
        name="upload"
        title="Upload"
        required
        decorator={[FormItem]}
        component={[NormalUpload]}
      />
      <Field
        name="upload2"
        title="Card upload"
        required
        decorator={[FormItem]}
        component={[CardUpload]}
      />
      <Field
        name="upload3"
        title="Drag and drop upload"
        required
        decorator={[FormItem]}
        component={[DraggerUpload]}
      />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>Submit</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## API

Reference https://fusion.design/pc/component/basic/upload

```

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

```markdown
# FormButtonGroup

> Form button group layout component

## Common case

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.FormItem>
          <Submit onSubmit={console.log}>Submit</Submit>
          <Reset>Reset</Reset>
        </FormButtonGroup.FormItem>
      </FormLayout>
    </FormProvider>
  )
}
```

## Suction bottom case

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.Sticky>
          <FormButtonGroup.FormItem>
            <Submit onSubmit={console.log}>Submit</Submit>
            <Reset>Reset</Reset>
          </FormButtonGroup.FormItem>
        </FormButtonGroup.Sticky>
      </FormLayout>
    </FormProvider>
  )
}
```

## Suction bottom centering case

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

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

const form = createForm()

export default () => {
  return (
    <FormProvider form={form}>
      <FormLayout labelCol={6} wrapperCol={10}>
        <SchemaField>
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
          <SchemaField.String
            title="input box"
            x-decorator="FormItem"
            required
            x-component="Input"
          />
        </SchemaField>
        <FormButtonGroup.Sticky align="center">
          <FormButtonGroup>
            <Submit onSubmit={console.log}>Submit</Submit>
            <Reset>Reset</Reset>
          </FormButtonGroup>
        </FormButtonGroup.Sticky>
      </FormLayout>
    </FormProvider>
  )
}
```

## API

### FormButtonGroup

> This component is mainly used to handle the button group gap

| Property name | Type                        | Description | Default value |
| ------------- | --------------------------- | ----------- | ------------- |
| gutter        | number                      | Gap size    | 8px           |
| align         | `'left'\|'center'\|'right'` | Alignment   | `'left'`      |

### FormButtonGroup.FormItem

> This component is mainly used to deal with the alignment of the button group and the main form FormItem

Refer to [FormItem](/components/form-item) property

### FormButtonGroup.Sticky

> This component is mainly used to deal with the floating positioning problem of the button group

| Property name | Type                        | Description | Default value |
| ------------- | --------------------------- | ----------- | ------------- |
| align         | `'left'\|'center'\|'right'` | Alignment   | `'left'`      |

```

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

```markdown
# DatePicker

> Date Picker

## Markup Schema example

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <SchemaField>
      <SchemaField.String
        name="date"
        required
        title="normal date"
        x-decorator="FormItem"
        x-component="DatePicker"
      />
      <SchemaField.String
        name="week"
        title="Week Selection"
        x-decorator="FormItem"
        x-component="DatePicker"
        x-component-props={{
          picker: 'week',
        }}
      />
      <SchemaField.String
        name="month"
        title="Month Selection"
        x-decorator="FormItem"
        x-component="DatePicker"
        x-component-props={{
          picker: 'month',
        }}
      />
      <SchemaField.String
        name="quarter"
        title="Financial Year Selection"
        x-decorator="FormItem"
        x-component="DatePicker"
        x-component-props={{
          picker: 'quarter',
        }}
      />
      <SchemaField.String
        name="year"
        title="Year selection"
        x-decorator="FormItem"
        x-component="DatePicker"
        x-component-props={{
          picker: 'year',
        }}
      />
      <SchemaField.String
        name="[startDate,endDate]"
        title="Date Range"
        x-decorator="FormItem"
        x-component="DatePicker.RangePicker"
        x-component-props={{
          showTime: true,
        }}
      />
      <SchemaField.String
        name="range_week"
        title="Week range selection"
        x-decorator="FormItem"
        x-component="DatePicker.RangePicker"
        x-component-props={{
          picker: 'week',
        }}
      />
      <SchemaField.String
        name="range_month"
        title="Month Range Selection"
        x-decorator="FormItem"
        x-component="DatePicker.RangePicker"
        x-component-props={{
          picker: 'month',
        }}
      />
      <SchemaField.String
        name="range_quarter"
        title="Financial Year Range Selection"
        x-decorator="FormItem"
        x-component="DatePicker.RangePicker"
        x-component-props={{
          picker: 'quarter',
        }}
      />
      <SchemaField.String
        name="range_year"
        title="Year range selection"
        x-decorator="FormItem"
        x-component="DatePicker.RangePicker"
        x-component-props={{
          picker: 'year',
        }}
      />
    </SchemaField>
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## JSON Schema case

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

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

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    date: {
      title: 'Normal date',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker',
      type: 'string',
    },
    week: {
      title: 'Week Selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker',
      'x-component-props': {
        picker: 'week',
      },
      type: 'string',
    },
    month: {
      title: 'Month Selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker',
      'x-component-props': {
        picker: 'month',
      },
      type: 'string',
    },
    quarter: {
      title: 'Fiscal Year Selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker',
      'x-component-props': {
        picker: 'quarter',
      },
      type: 'string',
    },
    year: {
      title: 'Year selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker',
      'x-component-props': {
        picker: 'year',
      },
      type: 'string',
    },
    '[startDate,endDate]': {
      title: 'Date range',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker.RangePicker',
      'x-component-props': {
        showTime: true,
      },
      type: 'string',
    },
    range_week: {
      title: 'Week range selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker.RangePicker',
      'x-component-props': {
        picker: 'week',
      },
      type: 'string',
    },
    range_month: {
      title: 'Month Range Selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker.RangePicker',
      'x-component-props': {
        picker: 'month',
      },
      type: 'string',
    },
    range_quarter: {
      title: 'Financial year range selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker.RangePicker',
      'x-component-props': {
        picker: 'quarter',
      },
      type: 'string',
    },
    range_year: {
      name: 'range_year',
      title: 'Year range selection',
      'x-decorator': 'FormItem',
      'x-component': 'DatePicker.RangePicker',
      'x-component-props': {
        picker: 'year',
      },
      type: 'string',
    },
  },
}

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

## Pure JSX case

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <Field
      name="date"
      title="date selection"
      decorator={[FormItem]}
      component={[DatePicker]}
    />
    <Field
      name="week"
      title="Week Selection"
      decorator={[FormItem]}
      component={[
        DatePicker,
        {
          picker: 'week',
        },
      ]}
    />
    <Field
      name="quarter"
      title="Financial Year Selection"
      decorator={[FormItem]}
      component={[
        DatePicker,
        {
          picker: 'month',
        },
      ]}
    />
    <Field
      name="year"
      title="Year selection"
      decorator={[FormItem]}
      component={[
        DatePicker,
        {
          picker: 'year',
        },
      ]}
    />
    <Field
      name="[startDate,endDate]"
      title="Date range selection"
      decorator={[FormItem]}
      component={[DatePicker.RangePicker]}
    />
    <Field
      name="range_week"
      title="Week range selection"
      decorator={[FormItem]}
      component={[
        DatePicker.RangePicker,
        {
          picker: 'week',
        },
      ]}
    />
    <Field
      name="range_month"
      title="Month Range Selection"
      decorator={[FormItem]}
      component={[
        DatePicker.RangePicker,
        {
          picker: 'month',
        },
      ]}
    />
    <Field
      name="range_quarter"
      title="Financial Year Range Selection"
      decorator={[FormItem]}
      component={[
        DatePicker.RangePicker,
        {
          picker: 'quarter',
        },
      ]}
    />
    <Field
      name="range_year"
      title="Year range selection"
      decorator={[FormItem]}
      component={[
        DatePicker.RangePicker,
        {
          picker: 'year',
        },
      ]}
    />
    <FormButtonGroup>
      <Submit onSubmit={console.log}>Submit</Submit>
    </FormButtonGroup>
  </FormProvider>
)
```

## API

Reference https://ant.design/components/date-picker-cn/

```

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

```typescript
import { inject, provide, Ref, ref, shallowRef, watch, isVue2 } from 'vue-demi'
import { GeneralField, isVoidField } from '@formily/core'
import { each, FormPath } from '@formily/shared'
import { observer } from '@formily/reactive-vue'
import { toJS, reaction } from '@formily/reactive'
import { SchemaOptionsSymbol, FieldSymbol, h, Fragment } from '../shared'
import { useAttach } from '../hooks/useAttach'
import { useField, useForm } from '../hooks'

import type {
  IReactiveFieldProps,
  VueComponentProps,
  DefineComponent,
} from '../types'
import type { VNode } from 'vue'

function isVueOptions(options: Record<string, unknown>) {
  return (
    typeof options.template === 'string' ||
    typeof options.render === 'function' ||
    typeof options.setup === 'function'
  )
}

const wrapFragment = (childNodes: VNode[] | VNode): VNode => {
  if (!Array.isArray(childNodes)) {
    return childNodes
  }
  if (childNodes.length > 1) {
    return h(Fragment, {}, { default: () => childNodes })
  }
  return childNodes[0]
}

const resolveComponent = (render: () => unknown[], extra?: any) => {
  if (extra === undefined || extra === null) {
    return render
  }
  if (typeof extra === 'string') {
    return () => [...render(), extra]
  }
  // not component
  if (!isVueOptions(extra) && typeof extra !== 'function') {
    return render
  }
  // for scoped slot
  if (extra.length > 1 || extra?.render?.length > 1) {
    return (scopedProps: VueComponentProps<any>) => [
      ...render(),
      h(extra, { props: scopedProps }, {}),
    ]
  }
  return () => [...render(), h(extra, {}, {})]
}

const mergeSlots = (
  field: GeneralField,
  slots: Record<string, any>,
  content: any
): Record<string, (...args: any) => any[]> => {
  const slotNames = Object.keys(slots)
  if (!slotNames.length) {
    if (!content) {
      return {}
    }
    if (typeof content === 'string') {
      return {
        default: resolveComponent(() => [], content),
      }
    }
  }
  const patchSlot =
    (slotName: string) =>
    (...originArgs) =>
      slots[slotName]?.({ field, form: field.form, ...originArgs[0] }) ?? []

  const patchedSlots: Record<string, (...args: any) => unknown[]> = {}
  slotNames.forEach((name) => {
    patchedSlots[name] = patchSlot(name)
  })

  // for named slots
  if (content && typeof content === 'object' && !isVueOptions(content)) {
    Object.keys(content).forEach((key) => {
      const child = content[key]
      const slot = patchedSlots[key] ?? (() => [])
      patchedSlots[key] = resolveComponent(slot, child)
    })
    return patchedSlots
  }
  // maybe default slot is empty
  patchedSlots['default'] = resolveComponent(
    patchedSlots['default'] ?? (() => []),
    content
  )
  return patchedSlots
}

const createFieldInVue2 = (innerCreateField) => {
  return () => {
    let res: GeneralField
    const disposer = reaction(() => {
      res = innerCreateField()
    })
    disposer()
    return res
  }
}

export default observer({
  name: 'ReactiveField',
  props: {
    fieldType: {
      type: String,
      default: 'Field',
    },
    fieldProps: {
      type: Object,
      default: () => ({}),
    },
  },
  setup(props: IReactiveFieldProps, { slots }) {
    const formRef = useForm()
    const parentRef = useField()
    const optionsRef = inject(SchemaOptionsSymbol, ref(null))
    let createField = () =>
      formRef?.value?.[`create${props.fieldType}`]?.({
        ...props.fieldProps,
        basePath: props.fieldProps?.basePath ?? parentRef.value?.address,
      })

    if (isVue2) {
      createField = createFieldInVue2(createField)
    }

    const fieldRef = shallowRef(createField()) as Ref<GeneralField>
    watch(
      () => props.fieldProps,
      () => (fieldRef.value = createField())
    )
    useAttach(fieldRef)
    provide(FieldSymbol, fieldRef)
    return () => {
      const field = fieldRef.value
      const options = optionsRef.value
      if (!field) {
        return slots.default?.()
      }
      if (field.display !== 'visible') {
        return h('template', {}, {})
      }

      const mergedSlots = mergeSlots(field, slots, field.content)

      const renderDecorator = (childNodes: any[]) => {
        if (!field.decoratorType) {
          return wrapFragment(childNodes)
        }
        const finalComponent =
          FormPath.getIn(options?.components, field.decoratorType as string) ??
          field.decoratorType
        const componentAttrs = toJS(field.decorator[1]) || {}

        const events: Record<string, any> = {}
        each(componentAttrs, (value, eventKey) => {
          const onEvent = eventKey.startsWith('on')
          const atEvent = eventKey.startsWith('@')
          if (!onEvent && !atEvent) return
          if (onEvent) {
            const eventName = `${eventKey[2].toLowerCase()}${eventKey.slice(3)}`
            // '@xxx' has higher priority
            events[eventName] = events[eventName] || value
          } else if (atEvent) {
            const eventName = eventKey.slice(1)
            events[eventName] = value
            delete componentAttrs[eventKey]
          }
        })

        const componentData = {
          attrs: componentAttrs,
          style: componentAttrs?.style,
          class: componentAttrs?.class,
          on: events,
        }
        delete componentData.attrs.style
        delete componentData.attrs.class

        return h(finalComponent, componentData, {
          default: () => childNodes,
        })
      }

      const renderComponent = () => {
        if (!field.componentType) return wrapFragment(mergedSlots?.default?.())

        const component =
          FormPath.getIn(options?.components, field.componentType as string) ??
          field.componentType

        const originData = toJS(field.component[1]) || {}
        const events = {} as Record<string, any>
        const originChange = originData['@change'] || originData['onChange']
        const originFocus = originData['@focus'] || originData['onFocus']
        const originBlur = originData['@blur'] || originData['onBlur']

        each(originData, (value, eventKey) => {
          const onEvent = eventKey.startsWith('on')
          const atEvent = eventKey.startsWith('@')
          if (!onEvent && !atEvent) return
          if (onEvent) {
            const eventName = `${eventKey[2].toLowerCase()}${eventKey.slice(3)}`
            // '@xxx' has higher priority
            events[eventName] = events[eventName] || value
          } else if (atEvent) {
            const eventName = eventKey.slice(1)
            events[eventName] = value
            delete originData[eventKey]
          }
        })

        events.change = (...args: any[]) => {
          if (!isVoidField(field)) field.onInput(...args)
          originChange?.(...args)
        }
        events.focus = (...args: any[]) => {
          if (!isVoidField(field)) field.onFocus(...args)
          originFocus?.(...args)
        }
        events.blur = (...args: any[]) => {
          if (!isVoidField(field)) field.onBlur(...args)
          originBlur?.(...args)
        }

        const componentData = {
          attrs: {
            disabled: !isVoidField(field)
              ? field.pattern === 'disabled' || field.pattern === 'readPretty'
              : undefined,
            readOnly: !isVoidField(field)
              ? field.pattern === 'readOnly'
              : undefined,
            ...originData,
            value: !isVoidField(field) ? field.value : undefined,
          },
          style: originData?.style,
          class: originData?.class,
          on: events,
        }
        delete componentData.attrs.style
        delete componentData.attrs.class

        return h(component, componentData, mergedSlots)
      }

      return renderDecorator([renderComponent()])
    }
  },
} as unknown as DefineComponent<IReactiveFieldProps>)

```

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

```typescript
import {
  Token,
  nameTok,
  colonTok,
  dotTok,
  starTok,
  dbStarTok,
  bangTok,
  bracketLTok,
  bracketRTok,
  bracketDRTok,
  expandTok,
  parenLTok,
  parenRTok,
  commaTok,
  eofTok,
  ignoreTok,
  braceLTok,
  braceRTok,
  bracketDLTok,
} from './tokens'
import { bracketDContext, Context } from './contexts'

const nonASCIIWhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/

const fullCharCodeAtPos = (input: string, pos: number) => {
  if (String.fromCharCode) return input.codePointAt(pos)
  const code = input.charCodeAt(pos)
  if (code <= 0xd7ff || code >= 0xe000) return code

  const next = input.charCodeAt(pos + 1)
  return (code << 10) + next - 0x35fdc00
}

const isRewordCode = (code: number) =>
  code === 42 ||
  code === 46 ||
  code === 33 ||
  code === 91 ||
  code === 93 ||
  code === 40 ||
  code === 41 ||
  code === 44 ||
  code === 58 ||
  code === 126 ||
  code === 123 ||
  code === 125

const getError = (message?: string, props?: any) => {
  const err = new Error(message)
  Object.assign(err, props)
  return err
}

const slice = (string: string, start: number, end: number) => {
  let str = ''
  for (let i = start; i < end; i++) {
    const ch = string.charAt(i)
    if (ch !== '\\') {
      str += ch
    }
  }
  return str
}

export class Tokenizer {
  public input: string
  public state: {
    context: Context[]
    type: Token
    pos: number
    value?: any
  }
  public type_: Token
  constructor(input: string) {
    this.input = input
    this.state = {
      context: [],
      type: null,
      pos: 0,
    }
    this.type_ = null
  }

  curContext() {
    return this.state.context[this.state.context.length - 1]
  }

  includesContext(context: Context) {
    for (let len = this.state.context.length - 1; len >= 0; len--) {
      if (this.state.context[len] === context) {
        return true
      }
    }
    return false
  }

  unexpect(type?: Token) {
    type = type || this.state.type
    return getError(
      `Unexpect token "${type.flag}" in ${this.state.pos} char.`,
      {
        pos: this.state.pos,
      }
    )
  }

  expectNext(type?: Token, next?: Token) {
    if (type && type.expectNext) {
      if (next && !type.expectNext.call(this, next)) {
        throw getError(
          `Unexpect token "${next.flag}" token should not be behind "${type.flag}" token.(${this.state.pos}th char)`,
          {
            pos: this.state.pos,
          }
        )
      }
    }
  }

  expectPrev(type?: Token, prev?: Token) {
    if (type && type.expectPrev) {
      if (prev && !type.expectPrev.call(this, prev)) {
        throw getError(
          `Unexpect token "${type.flag}" should not be behind "${prev.flag}"(${this.state.pos}th char).`,
          {
            pos: this.state.pos,
          }
        )
      }
    }
  }

  match(type?: Token) {
    return this.state.type === type
  }

  skipSpace() {
    if (this.curContext() === bracketDContext) return
    loop: while (this.state.pos < this.input.length) {
      const ch = this.input.charCodeAt(this.state.pos)
      switch (ch) {
        case 32:
        case 160:
          ++this.state.pos
          break

        case 13:
          if (this.input.charCodeAt(this.state.pos + 1) === 10) {
            ++this.state.pos
          }

        case 10:
        case 8232:
        case 8233:
          ++this.state.pos
          break
        default:
          if (
            (ch > 8 && ch < 14) ||
            (ch >= 5760 && nonASCIIWhitespace.test(String.fromCharCode(ch)))
          ) {
            ++this.state.pos
          } else {
            break loop
          }
      }
    }
  }

  next() {
    this.type_ = this.state.type
    if (this.input.length <= this.state.pos) {
      return this.finishToken(eofTok)
    }
    this.skipSpace()
    this.readToken(
      this.getCode(),
      this.state.pos > 0 ? this.getCode(this.state.pos - 1) : -Infinity
    )
  }

  getCode(pos = this.state.pos) {
    return fullCharCodeAtPos(this.input, pos)
  }

  eat(type) {
    if (this.match(type)) {
      this.next()
      return true
    } else {
      return false
    }
  }

  readKeyWord() {
    let startPos = this.state.pos,
      string = ''
    while (true) {
      const code = this.getCode()
      const prevCode = this.getCode(this.state.pos - 1)
      if (this.input.length === this.state.pos) {
        string = slice(this.input, startPos, this.state.pos + 1)
        break
      }
      if (!isRewordCode(code) || prevCode === 92) {
        if (
          code === 32 ||
          code === 160 ||
          code === 10 ||
          code === 8232 ||
          code === 8233
        ) {
          string = slice(this.input, startPos, this.state.pos)
          break
        }
        if (code === 13 && this.input.charCodeAt(this.state.pos + 1) === 10) {
          string = slice(this.input, startPos, this.state.pos)
          break
        }
        if (
          (code > 8 && code < 14) ||
          (code >= 5760 && nonASCIIWhitespace.test(String.fromCharCode(code)))
        ) {
          string = slice(this.input, startPos, this.state.pos)
          break
        }
        this.state.pos++
      } else {
        string = slice(this.input, startPos, this.state.pos)
        break
      }
    }

    this.finishToken(nameTok, string)
  }

  readIgnoreString() {
    let startPos = this.state.pos,
      prevCode,
      string = ''
    while (true) {
      const code = this.getCode()
      if (this.state.pos >= this.input.length) break
      if ((code === 91 || code === 93) && prevCode === 92) {
        this.state.pos++
        prevCode = ''
      } else if (code == 93 && prevCode === 93) {
        string = this.input
          .slice(startPos, this.state.pos - 1)
          .replace(/\\([\[\]])/g, '$1')
        this.state.pos++
        break
      } else {
        this.state.pos++
        prevCode = code
      }
    }

    this.finishToken(ignoreTok, string)
    this.finishToken(bracketDRTok)
  }

  finishToken(type: Token, value?: any) {
    const preType = this.state.type
    this.state.type = type
    if (value !== undefined) this.state.value = value
    this.expectNext(preType, type)
    this.expectPrev(type, preType)
    if (type.updateContext) {
      type.updateContext.call(this, preType)
    }
  }

  readToken(code: number, prevCode: number) {
    if (prevCode === 92) {
      return this.readKeyWord()
    }
    if (this.input.length <= this.state.pos) {
      this.finishToken(eofTok)
    } else if (this.curContext() === bracketDContext) {
      this.readIgnoreString()
    } else if (code === 123) {
      this.state.pos++
      this.finishToken(braceLTok)
    } else if (code === 125) {
      this.state.pos++
      this.finishToken(braceRTok)
    } else if (code === 42) {
      this.state.pos++
      if (this.getCode() === 42) {
        this.state.pos++
        return this.finishToken(dbStarTok)
      }
      this.finishToken(starTok)
    } else if (code === 33) {
      this.state.pos++
      this.finishToken(bangTok)
    } else if (code === 46) {
      this.state.pos++
      this.finishToken(dotTok)
    } else if (code === 91) {
      this.state.pos++
      if (this.getCode() === 91) {
        this.state.pos++
        return this.finishToken(bracketDLTok)
      }
      this.finishToken(bracketLTok)
    } else if (code === 126) {
      this.state.pos++
      this.finishToken(expandTok)
    } else if (code === 93) {
      this.state.pos++
      this.finishToken(bracketRTok)
    } else if (code === 40) {
      this.state.pos++
      this.finishToken(parenLTok)
    } else if (code === 41) {
      this.state.pos++
      this.finishToken(parenRTok)
    } else if (code === 44) {
      this.state.pos++
      this.finishToken(commaTok)
    } else if (code === 58) {
      this.state.pos++
      this.finishToken(colonTok)
    } else {
      this.readKeyWord()
    }
  }
}

```

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

```typescript
import {
  bindTargetKeyWithCurrentReaction,
  runReactionsFromTargetKey,
} from './reaction'
import { ProxyRaw, RawProxy } from './environment'
import { isObservable, isSupportObservable } from './externals'
import { createObservable } from './internals'

const wellKnownSymbols = new Set(
  Object.getOwnPropertyNames(Symbol).reduce((buf: Symbol[], key) => {
    if (key === 'arguments' || key === 'caller') return buf
    const value = Symbol[key]
    if (typeof value === 'symbol') return buf.concat(value)
    return buf
  }, [])
)

const hasOwnProperty = Object.prototype.hasOwnProperty

function findObservable(target: any, key: PropertyKey, value: any) {
  const observableObj = RawProxy.get(value)
  if (observableObj) {
    return observableObj
  }
  if (!isObservable(value) && isSupportObservable(value)) {
    return createObservable(target, key, value)
  }
  return value
}

function patchIterator(
  target: any,
  key: PropertyKey,
  iterator: IterableIterator<any>,
  isEntries: boolean
) {
  const originalNext = iterator.next
  iterator.next = () => {
    let { done, value } = originalNext.call(iterator)
    if (!done) {
      if (isEntries) {
        value[1] = findObservable(target, key, value[1])
      } else {
        value = findObservable(target, key, value)
      }
    }
    return { done, value }
  }
  return iterator
}

const instrumentations = {
  has(key: PropertyKey) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, key, type: 'has' })
    return proto.has.apply(target, arguments)
  },
  get(key: PropertyKey) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, key, type: 'get' })
    return findObservable(target, key, proto.get.apply(target, arguments))
  },
  add(key: PropertyKey) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    const hadKey = proto.has.call(target, key)
    // forward the operation before queueing reactions
    const result = proto.add.apply(target, arguments)
    if (!hadKey) {
      runReactionsFromTargetKey({ target, key, value: key, type: 'add' })
    }
    return result
  },
  set(key: PropertyKey, value: any) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    const hadKey = proto.has.call(target, key)
    const oldValue = proto.get.call(target, key)
    // forward the operation before queueing reactions
    const result = proto.set.apply(target, arguments)
    if (!hadKey) {
      runReactionsFromTargetKey({ target, key, value, type: 'add' })
    } else if (value !== oldValue) {
      runReactionsFromTargetKey({ target, key, value, oldValue, type: 'set' })
    }
    return result
  },
  delete(key: PropertyKey) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    const hadKey = proto.has.call(target, key)
    const oldValue = proto.get ? proto.get.call(target, key) : undefined
    // forward the operation before queueing reactions
    const result = proto.delete.apply(target, arguments)
    if (hadKey) {
      runReactionsFromTargetKey({ target, key, oldValue, type: 'delete' })
    }
    return result
  },
  clear() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    const hadItems = target.size !== 0
    const oldTarget = target instanceof Map ? new Map(target) : new Set(target)
    // forward the operation before queueing reactions
    const result = proto.clear.apply(target, arguments)
    if (hadItems) {
      runReactionsFromTargetKey({ target, oldTarget, type: 'clear' })
    }
    return result
  },
  forEach(cb: any, ...args: any[]) {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    // swap out the raw values with their observable pairs
    // before passing them to the callback
    const wrappedCb = (value: any, key: PropertyKey, ...args: any) =>
      cb(findObservable(target, key, value), key, ...args)
    return proto.forEach.call(target, wrappedCb, ...args)
  },
  keys() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    return proto.keys.apply(target, arguments)
  },
  values() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    const iterator = proto.values.apply(target, arguments)
    return patchIterator(target, '', iterator, false)
  },
  entries() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this) as any
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    const iterator = proto.entries.apply(target, arguments)
    return patchIterator(target, '', iterator, true)
  },
  [Symbol.iterator]() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this)
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    const iterator = proto[Symbol.iterator].apply(target, arguments)
    return patchIterator(target, '', iterator, target instanceof Map)
  },
  get size() {
    const target = ProxyRaw.get(this)
    const proto = Reflect.getPrototypeOf(this)
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    return Reflect.get(proto, 'size', target)
  },
}

export const collectionHandlers = {
  get(target: any, key: PropertyKey, receiver: any) {
    // instrument methods and property accessors to be reactive
    target = hasOwnProperty.call(instrumentations, key)
      ? instrumentations
      : target
    return Reflect.get(target, key, receiver)
  },
}

export const baseHandlers: ProxyHandler<any> = {
  get(target, key, receiver) {
    if (!key) return
    const result = target[key] // use Reflect.get is too slow
    if (typeof key === 'symbol' && wellKnownSymbols.has(key)) {
      return result
    }
    bindTargetKeyWithCurrentReaction({ target, key, receiver, type: 'get' })
    const observableResult = RawProxy.get(result)
    if (observableResult) {
      return observableResult
    }
    if (!isObservable(result) && isSupportObservable(result)) {
      const descriptor = Reflect.getOwnPropertyDescriptor(target, key)
      if (
        !descriptor ||
        !(descriptor.writable === false && descriptor.configurable === false)
      ) {
        return createObservable(target, key, result)
      }
    }
    return result
  },
  has(target, key) {
    const result = Reflect.has(target, key)
    bindTargetKeyWithCurrentReaction({ target, key, type: 'has' })
    return result
  },
  ownKeys(target) {
    const keys = Reflect.ownKeys(target)
    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })
    return keys
  },
  set(target, key, value, receiver) {
    // vue2中有对数组原型重写,因此需去除此处proxy
    if (key === '__proto__') {
      target[key] = value
      return true
    }
    const hadKey = hasOwnProperty.call(target, key)
    const newValue = createObservable(target, key, value)
    const oldValue = target[key]
    target[key] = newValue // use Reflect.set is too slow
    if (!hadKey) {
      runReactionsFromTargetKey({
        target,
        key,
        value: newValue,
        oldValue,
        receiver,
        type: 'add',
      })
    } else if (value !== oldValue) {
      runReactionsFromTargetKey({
        target,
        key,
        value: newValue,
        oldValue,
        receiver,
        type: 'set',
      })
    }
    return true
  },
  deleteProperty(target, key) {
    const oldValue = target[key]
    delete target[key]
    runReactionsFromTargetKey({
      target,
      key,
      oldValue,
      type: 'delete',
    })
    return true
  },
}

```

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

```markdown
# Space

> 超级便捷的 Flex 布局组件,可以帮助用户快速实现任何元素的并排紧挨布局

## Markup Schema 案例

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

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={16}>
      <SchemaField>
        <SchemaField.Void
          title="姓名"
          x-decorator="FormItem"
          x-decorator-props={{
            asterisk: true,
            feedbackLayout: 'none',
          }}
          x-component="Space"
        >
          <SchemaField.String
            name="firstName"
            x-decorator="FormItem"
            x-component="Input"
            required
          />
          <SchemaField.String
            name="lastName"
            x-decorator="FormItem"
            x-component="Input"
            required
          />
        </SchemaField.Void>
        <SchemaField.Void
          title="文本串联"
          x-decorator="FormItem"
          x-decorator-props={{
            asterisk: true,
            feedbackLayout: 'none',
          }}
          x-component="Space"
        >
          <SchemaField.String
            name="aa"
            x-decorator="FormItem"
            x-component="Input"
            x-decorator-props={{
              addonAfter: '单位',
            }}
            required
          />
          <SchemaField.String
            name="bb"
            x-decorator="FormItem"
            x-component="Input"
            x-decorator-props={{
              addonAfter: '单位',
            }}
            required
          />
          <SchemaField.String
            name="cc"
            x-decorator="FormItem"
            x-component="Input"
            x-decorator-props={{
              addonAfter: '单位',
            }}
            required
          />
        </SchemaField.Void>
        <SchemaField.String
          name="textarea"
          title="文本框"
          x-decorator="FormItem"
          required
          x-component="Input.TextArea"
          x-component-props={{
            style: {
              width: 400,
            },
          }}
        />
      </SchemaField>
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>提交</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## JSON Schema 案例

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

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

const form = createForm()

const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'void',
      title: '姓名',
      'x-decorator': 'FormItem',
      'x-decorator-props': {
        asterisk: true,
        feedbackLayout: 'none',
      },
      'x-component': 'Space',
      properties: {
        firstName: {
          type: 'string',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
          required: true,
        },
        lastName: {
          type: 'string',
          'x-decorator': 'FormItem',
          'x-component': 'Input',
          required: true,
        },
      },
    },
    texts: {
      type: 'void',
      title: '文本串联',
      'x-decorator': 'FormItem',
      'x-decorator-props': {
        asterisk: true,
        feedbackLayout: 'none',
      },
      'x-component': 'Space',
      properties: {
        aa: {
          type: 'string',
          'x-decorator': 'FormItem',
          'x-decorator-props': {
            addonAfter: '单位',
          },
          'x-component': 'Input',
          required: true,
        },
        bb: {
          type: 'string',
          'x-decorator': 'FormItem',
          'x-decorator-props': {
            addonAfter: '单位',
          },
          'x-component': 'Input',
          required: true,
        },
        cc: {
          type: 'string',
          'x-decorator': 'FormItem',
          'x-decorator-props': {
            addonAfter: '单位',
          },
          'x-component': 'Input',
          required: true,
        },
      },
    },

    textarea: {
      type: 'string',
      title: '文本框',
      'x-decorator': 'FormItem',
      'x-component': 'Input.TextArea',
      'x-component-props': {
        style: {
          width: 400,
        },
      },
      required: true,
    },
  },
}

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={16}>
      <SchemaField schema={schema} />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>提交</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## 纯 JSX 案例

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

const form = createForm()

export default () => (
  <FormProvider form={form}>
    <FormLayout labelCol={6} wrapperCol={16}>
      <VoidField
        name="name"
        title="姓名"
        decorator={[
          FormItem,
          {
            asterisk: true,
            feedbackLayout: 'none',
          },
        ]}
        component={[Space]}
      >
        <Field
          name="firstName"
          decorator={[FormItem]}
          component={[Input]}
          required
        />
        <Field
          name="lastName"
          decorator={[FormItem]}
          component={[Input]}
          required
        />
      </VoidField>
      <VoidField
        name="texts"
        title="文本串联"
        decorator={[
          FormItem,
          {
            asterisk: true,
            feedbackLayout: 'none',
          },
        ]}
        component={[Space]}
      >
        <Field
          name="aa"
          decorator={[
            FormItem,
            {
              addonAfter: '单位',
            },
          ]}
          component={[Input]}
          required
        />
        <Field
          name="bb"
          decorator={[
            FormItem,
            {
              addonAfter: '单位',
            },
          ]}
          component={[Input]}
          required
        />
        <Field
          name="cc"
          decorator={[
            FormItem,
            {
              addonAfter: '单位',
            },
          ]}
          component={[Input]}
          required
        />
      </VoidField>
      <Field
        name="textarea"
        title="文本框"
        decorator={[FormItem]}
        component={[
          Input.TextArea,
          {
            style: {
              width: 400,
            },
          },
        ]}
        required
      />
      <FormButtonGroup.FormItem>
        <Submit onSubmit={console.log}>提交</Submit>
      </FormButtonGroup.FormItem>
    </FormLayout>
  </FormProvider>
)
```

## API

| 属性名    | 类型                                         | 描述     | 默认值    |
| --------- | -------------------------------------------- | -------- | --------- |
| style     | CSSProperties                                | 样式     | -         |
| className | string                                       | 类名     | -         |
| prefix    | string                                       | 样式前缀 | true      |
| size      | `number \| 'small' \| 'large' \| 'middle'`   | 间隔尺寸 | 8px       |
| direction | `'horizontal' \| 'vertical'`                 | 方向     | -         |
| align     | `'start' \| 'end' \| 'center' \| 'baseline'` | 对齐     | `'start'` |
| wrap      | boolean                                      | 是否换行 | false     |

```

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

```markdown
# FormDrawer

> Drawer form, mainly used in simple event to open form scene

## Markup Schema example

```tsx
import React from 'react'
import {
  FormDrawer,
  FormItem,
  FormLayout,
  Input,
  Submit,
  Reset,
  FormButtonGroup,
} from '@formily/antd'
import { createSchemaField } from '@formily/react'
import { Button } from 'antd'

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

export default () => {
  return (
    <Button
      onClick={() => {
        FormDrawer('Drawer Form', () => {
          return (
            <FormLayout labelCol={6} wrapperCol={10}>
              <SchemaField>
                <SchemaField.String
                  name="aaa"
                  required
                  title="input box 1"
                  x-decorator="FormItem"
                  x-component="Input"
                />
                <SchemaField.String
                  name="bbb"
                  required
                  title="input box 2"
                  x-decorator="FormItem"
                  x-component="Input"
                />
                <SchemaField.String
                  name="ccc"
                  required
                  title="input box 3"
                  x-decorator="FormItem"
                  x-component="Input"
                />
                <SchemaField.String
                  name="ddd"
                  required
                  title="input box 4"
                  x-decorator="FormItem"
                  x-component="Input"
                />
              </SchemaField>
              <FormDrawer.Extra>
                <FormButtonGroup align="right">
                  <Submit
                    onSubmit={() => {
                      return new Promise((resolve) => {
                        setTimeout(resolve, 1000)
                      })
                    }}
                  >
                    Submit
                  </Submit>
                  <Reset>Reset</Reset>
                </FormButtonGroup>
              </FormDrawer.Extra>
            </FormLayout>
          )
        })
          .forOpen((props, next) => {
            setTimeout(() => {
              next({
                initialValues: {
                  aaa: '123',
                },
              })
            }, 1000)
          })
          .open()
          .then(console.log)
      }}
    >
      Click me to open the form
    </Button>
  )
}
```

## JSON Schema case

```tsx
import React from 'react'
import {
  FormDrawer,
  FormItem,
  FormLayout,
  Input,
  Submit,
  Reset,
  FormButtonGroup,
} from '@formily/antd'
import { createSchemaField } from '@formily/react'
import { Button } from 'antd'

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

const schema = {
  type: 'object',
  properties: {
    aaa: {
      type: 'string',
      title: 'input box 1',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
    bbb: {
      type: 'string',
      title: 'input box 2',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
    ccc: {
      type: 'string',
      title: 'input box 3',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
    ddd: {
      type: 'string',
      title: 'input box 4',
      required: true,
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
  },
}

export default () => {
  return (
    <Button
      onClick={() => {
        FormDrawer('Pop-up form', () => {
          return (
            <FormLayout labelCol={6} wrapperCol={10}>
              <SchemaField schema={schema} />
              <FormDrawer.Extra>
                <FormButtonGroup align="right">
                  <Submit
                    onSubmit={() => {
                      return new Promise((resolve) => {
                        setTimeout(resolve, 1000)
                      })
                    }}
                  >
                    Submit
                  </Submit>
                  <Reset>Reset</Reset>
                </FormButtonGroup>
              </FormDrawer.Extra>
            </FormLayout>
          )
        })
          .open({
            initialValues: {
              aaa: '123',
            },
          })
          .then(console.log)
      }}
    >
      Click me to open the form
    </Button>
  )
}
```

## Pure JSX case

```tsx
import React from 'react'
import {
  FormDrawer,
  FormItem,
  FormLayout,
  Input,
  Submit,
  Reset,
  FormButtonGroup,
} from '@formily/antd'
import { Field } from '@formily/react'
import { Button } from 'antd'

export default () => {
  return (
    <Button
      onClick={() => {
        FormDrawer('Pop-up form', () => {
          return (
            <FormLayout labelCol={6} wrapperCol={10}>
              <Field
                name="aaa"
                required
                title="input box 1"
                decorator={[FormItem]}
                component={[Input]}
              />
              <Field
                name="bbb"
                required
                title="input box 2"
                decorator={[FormItem]}
                component={[Input]}
              />
              <Field
                name="ccc"
                required
                title="input box 3"
                decorator={[FormItem]}
                component={[Input]}
              />
              <Field
                name="ddd"
                required
                title="input box 4"
                decorator={[FormItem]}
                component={[Input]}
              />
              <FormDrawer.Extra>
                <FormButtonGroup align="right">
                  <Submit
                    onSubmit={() => {
                      return new Promise((resolve) => {
                        setTimeout(resolve, 1000)
                      })
                    }}
                  >
                    Submit
                  </Submit>
                  <Reset>Reset</Reset>
                </FormButtonGroup>
              </FormDrawer.Extra>
            </FormLayout>
          )
        })
          .open({
            initialValues: {
              aaa: '123',
            },
          })
          .then(console.log)
      }}
    >
      Click me to open the form
    </Button>
  )
}
```

## API

### FormDrawer

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

type FormDrawerRenderer =
  | React.ReactElement
  | ((form: Form) => React.ReactElement)

interface IFormDrawer {
  forOpen(
    middleware: (
      props: IFormProps,
      next: (props?: IFormProps) => Promise<any>
    ) => any
  ): any //Middleware interceptor, can intercept Drawer to open
  //Open the pop-up window to receive form attributes, you can pass in initialValues/values/effects etc.
  open(props: IFormProps): Promise<any> //return form data
  //Close the pop-up window
  close(): void
}

export interface IDrawerProps extends DrawerProps {
  onClose?: (e: EventType) => void | boolean // return false can prevent onClose
  loadingText?: React.ReactNode
}

interface FormDrawer {
  (title: IDrawerProps, id: string, renderer: FormDrawerRenderer): IFormDrawer
  (title: IDrawerProps, renderer: FormDrawerRenderer): IFormDrawer
  (title: ModalTitle, id: string, renderer: FormDrawerRenderer): IFormDrawer
  (title: ModalTitle, renderer: FormDrawerRenderer): IFormDrawer
}
```

`DrawerProps` type definition reference ant design [Drawer API](https://ant.design/components/drawer-cn/#API)

### FormDrawer.Extra

No attributes, only child nodes are received

### FormDrawer.Footer

No attributes, only child nodes are received

### FormDrawer.Portal

Receive an optional id attribute, the default value is `form-drawer`, if there are multiple prefixCls in an application, and the prefixCls in the pop-up window of different regions are different, then it is recommended to specify the id as the region-level id

```

--------------------------------------------------------------------------------
/packages/next/src/preview-text/index.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { createContext, useContext } from 'react'
import { isArr, isEmpty, isValid } from '@formily/shared'
import { Field } from '@formily/core'
import { useField, observer } from '@formily/react'
import { InputProps } from '@alifd/next/lib/input'
import { NumberPickerProps } from '@alifd/next/lib/number-picker'
import { SelectProps } from '@alifd/next/lib/select'
import { TreeSelectProps } from '@alifd/next/lib/tree-select'
import { CascaderSelectProps } from '@alifd/next/lib/cascader-select'
import {
  DatePickerProps,
  RangePickerProps as DateRangePickerProps,
} from '@alifd/next/lib/date-picker'
import { TimePickerProps } from '@alifd/next/lib/time-picker'
import {
  TimePickerProps as TimePicker2Props,
  RangePickerProps as TimeRangePicker2Props,
} from '@alifd/next/types/time-picker2'
import {
  Tag,
  Input as NextInput,
  NumberPicker as NextNumberPicker,
  CascaderSelect as NextCascader,
} from '@alifd/next'
import cls from 'classnames'
import { formatMomentValue, usePrefixCls } from '../__builtins__'

const PlaceholderContext = createContext<React.ReactNode>('N/A')

const Placeholder = PlaceholderContext.Provider

const usePlaceholder = (value?: any) => {
  const placeholder = useContext(PlaceholderContext) || 'N/A'
  return !isEmpty(value) ? value : placeholder
}

const Input: React.FC<React.PropsWithChildren<InputProps>> = (props) => {
  return <NextInput {...props} isPreview />
}

const NumberPicker: React.FC<React.PropsWithChildren<NumberPickerProps>> = (
  props
) => {
  return <NextNumberPicker {...props} isPreview />
}

const Select: React.FC<React.PropsWithChildren<SelectProps>> = observer(
  (props) => {
    const field = useField<Field>()
    const prefixCls = usePrefixCls('form-preview', props)
    const dataSource: any[] = field?.dataSource?.length
      ? field.dataSource
      : props?.dataSource?.length
      ? props.dataSource
      : []
    const placeholder = usePlaceholder()
    const getSelected = () => {
      const value = props.value
      if (props.mode === 'multiple' || props.mode === 'tag') {
        if (props.useDetailValue) {
          return isArr(value) ? value : []
        } else {
          return isArr(value)
            ? value.map((val) => ({ label: val, value: val }))
            : []
        }
      } else {
        if (props.useDetailValue) {
          return isValid(value) ? [value] : []
        } else {
          return isValid(value) ? [{ label: value, value }] : []
        }
      }
    }

    const getLabel = (target: any) => {
      return (
        dataSource?.find((item) => item.value == target?.value)?.label ||
        target.label ||
        placeholder
      )
    }

    const getLabels = () => {
      const selected = getSelected()
      if (!selected.length) return placeholder
      if (selected.length === 1) return getLabel(selected[0])
      return selected.map((item, key) => {
        return (
          <Tag type="primary" size="small" key={key}>
            {getLabel(item)}
          </Tag>
        )
      })
    }

    return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
  }
)

const TreeSelect: React.FC<React.PropsWithChildren<TreeSelectProps>> = observer(
  (props) => {
    const field = useField<Field>()
    const placeholder = usePlaceholder()
    const prefixCls = usePrefixCls('form-preview', props)
    const dataSource = field?.dataSource?.length
      ? field.dataSource
      : props?.dataSource?.length
      ? props.dataSource
      : []
    const getSelected = () => {
      const value = props.value
      if (props.multiple) {
        if (props['useDetailValue']) {
          return isArr(value) ? value : []
        } else {
          return isArr(value)
            ? value.map((val) => ({ label: val, value: val }))
            : []
        }
      } else {
        if (props['useDetailValue']) {
          return value ? [value] : []
        } else {
          return value ? [{ label: value, value }] : []
        }
      }
    }

    const findLabel = (value: any, dataSource: any[]) => {
      for (let i = 0; i < dataSource?.length; i++) {
        const item = dataSource[i]
        if (item?.value === value) {
          return item?.label
        } else {
          const childLabel = findLabel(value, item?.children)
          if (childLabel) return childLabel
        }
      }
    }

    const getLabels = () => {
      const selected = getSelected()
      if (!selected?.length)
        return (
          <Tag type="primary" size="small">
            {placeholder}
          </Tag>
        )
      return selected.map(({ value, label }, key) => {
        return (
          <Tag type="primary" size="small" key={key}>
            {findLabel(value, dataSource) || label || placeholder}
          </Tag>
        )
      })
    }
    return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
  }
)

const Cascader: React.FC<React.PropsWithChildren<CascaderSelectProps>> =
  observer((props) => {
    const field = useField<Field>()
    const prefixCls = usePrefixCls('form-preview', props)
    return (
      <NextCascader
        {...props}
        className={prefixCls}
        dataSource={field.dataSource}
        isPreview
      />
    )
  })

const DatePicker: React.FC<React.PropsWithChildren<DatePickerProps>> = (
  props
) => {
  const placeholder = usePlaceholder()
  const prefixCls = usePrefixCls('form-preview', props)
  const getLabels = () => {
    const labels = formatMomentValue(props.value, props.format, placeholder)
    return isArr(labels) ? labels.join('~') : labels
  }
  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
}

const DateRangePicker: React.FC<
  React.PropsWithChildren<DateRangePickerProps>
> = (props) => {
  const placeholder = usePlaceholder()
  const prefixCls = usePrefixCls('form-preview', props)
  const getLabels = () => {
    const labels = formatMomentValue(props.value, props.format, placeholder)
    return isArr(labels) ? labels.join('~') : labels
  }
  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
}

const TimePicker: React.FC<React.PropsWithChildren<TimePickerProps>> = (
  props
) => {
  const placeholder = usePlaceholder()
  const prefixCls = usePrefixCls('form-preview', props)
  const getLabels = () => {
    const labels = formatMomentValue(props.value, props.format, placeholder)
    return isArr(labels) ? labels.join('~') : labels
  }
  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
}

const TimePicker2: React.FC<React.PropsWithChildren<TimePicker2Props>> = (
  props
) => {
  const placeholder = usePlaceholder()
  const prefixCls = usePrefixCls('form-preview', props)
  const getLabels = () => {
    const labels = formatMomentValue(props.value, props.format, placeholder)
    return isArr(labels) ? labels.join('~') : labels
  }
  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
}

const TimeRangePicker2: React.FC<
  React.PropsWithChildren<TimeRangePicker2Props>
> = (props) => {
  const placeholder = usePlaceholder()
  const prefixCls = usePrefixCls('form-preview', props)
  const getLabels = () => {
    const labels = formatMomentValue(props.value, props.format, placeholder)
    return isArr(labels) ? labels.join('~') : labels
  }
  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>
}

const Text = (props: React.PropsWithChildren<any>) => {
  const prefixCls = usePrefixCls('form-preview', props)

  return (
    <div className={cls(prefixCls, props.className)} style={props.style}>
      {usePlaceholder(props.value)}
    </div>
  )
}

Text.Input = Input
Text.NumberPicker = NumberPicker
Text.Select = Select
Text.TreeSelect = TreeSelect
Text.Cascader = Cascader
Text.DatePicker = DatePicker
Text.DateRangePicker = DateRangePicker
Text.TimePicker = TimePicker
Text.TimePicker2 = TimePicker2
Text.TimeRangePicker2 = TimeRangePicker2
Text.Placeholder = Placeholder
Text.usePlaceholder = usePlaceholder

export const PreviewText = Text

export default PreviewText

```

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

```typescript
import { observable, autorun, raw } from '..'

describe('Set', () => {
  test('should be a proper JS Set', () => {
    const set = observable(new Set())
    expect(set).toBeInstanceOf(Set)
    expect(raw(set)).toBeInstanceOf(Set)
  })

  test('should autorun mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set.has('value')))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(false)
    set.add('value')
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(true)
    set.delete('value')
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(false)
  })

  test('should autorun size mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set.size))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add('value')
    set.add('value2')
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(2)
    set.delete('value')
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(1)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should autorun for of iteration', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      // eslint-disable-next-line no-unused-vars
      for (let num of set) {
        sum += num
      }
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(3)
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(3)
    set.add(2)
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(5)
    set.delete(3)
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(2)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should autorun forEach iteration', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      set.forEach((num) => (sum += num))
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(3)
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(3)
    set.add(2)
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(5)
    set.delete(3)
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(2)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should autorun keys iteration', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      for (let key of set.keys()) {
        sum += key
      }
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(3)
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(3)
    set.add(2)
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(5)
    set.delete(3)
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(2)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should autorun values iteration', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      for (let num of set.values()) {
        sum += num
      }
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(3)
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(3)
    set.add(2)
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(5)
    set.delete(3)
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(2)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should autorun entries iteration', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      // eslint-disable-next-line no-unused-vars
      for (let [, num] of set.entries()) {
        sum += num
      }
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(3)
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(3)
    set.add(2)
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(5)
    set.delete(3)
    expect(handler).toBeCalledTimes(4)
    expect(handler).lastCalledWith(2)
    set.clear()
    expect(handler).toBeCalledTimes(5)
    expect(handler).lastCalledWith(0)
  })

  test('should not autorun custom property mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set['customProp']))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(undefined)
    set['customProp'] = 'Hello World'
    expect(handler).toBeCalledTimes(1)
  })

  test('should not autorun non value changing mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set.has('value')))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(false)
    set.add('value')
    expect(handler).toBeCalledTimes(2)
    expect(handler).lastCalledWith(true)
    set.add('value')
    expect(handler).toBeCalledTimes(2)
    set.delete('value')
    expect(handler).toBeCalledTimes(3)
    expect(handler).lastCalledWith(false)
    set.delete('value')
    expect(handler).toBeCalledTimes(3)
    set.clear()
    expect(handler).toBeCalledTimes(3)
  })

  test('should not autorun raw data', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(raw(set).has('value')))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(false)
    set.add('value')
    expect(handler).toBeCalledTimes(1)
    set.delete('value')
    expect(handler).toBeCalledTimes(1)
  })

  test('should not autorun raw iterations', () => {
    const handler = jest.fn()
    const set = observable(new Set<number>())
    autorun(() => {
      let sum = 0
      // eslint-disable-next-line no-unused-vars
      for (let [, num] of raw(set).entries()) {
        sum += num
      }
      for (let key of raw(set).keys()) {
        sum += key
      }
      for (let num of raw(set).values()) {
        sum += num
      }
      raw(set).forEach((num) => {
        sum += num
      })
      // eslint-disable-next-line no-unused-vars
      for (let num of raw(set)) {
        sum += num
      }
      handler(sum)
    })

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add(2)
    set.add(3)
    expect(handler).toBeCalledTimes(1)
    set.delete(2)
    expect(handler).toBeCalledTimes(1)
  })

  test('should not be triggered by raw mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set.has('value')))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(false)
    raw(set).add('value')
    expect(handler).toBeCalledTimes(1)
    raw(set).delete('value')
    expect(handler).toBeCalledTimes(1)
    raw(set).clear()
    expect(handler).toBeCalledTimes(1)
  })

  test('should not autorun raw size mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(raw(set).size))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    set.add('value')
    expect(handler).toBeCalledTimes(1)
  })

  test('should not be triggered by raw size mutations', () => {
    const handler = jest.fn()
    const set = observable(new Set())
    autorun(() => handler(set.size))

    expect(handler).toBeCalledTimes(1)
    expect(handler).lastCalledWith(0)
    raw(set).add('value')
    expect(handler).toBeCalledTimes(1)
  })
})

```
Page 16/35FirstPrevNextLast