This is page 37 of 52. Use http://codebase.md/alibaba/formily?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .all-contributorsrc ├── .codecov.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github │ ├── CONTRIBUTING.md │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE │ │ └── config.yml │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows │ ├── check-pr-title.yml │ ├── ci.yml │ ├── commitlint.yml │ ├── issue-open-check.yml │ ├── package-size.yml │ └── pr-welcome.yml ├── .gitignore ├── .prettierrc.js ├── .umirc.js ├── .vscode │ └── cspell.json ├── .yarnrc ├── CHANGELOG.md ├── commitlint.config.js ├── devtools │ ├── .eslintrc │ └── chrome-extension │ ├── .npmignore │ ├── assets │ │ └── img │ │ ├── loading.svg │ │ └── logo │ │ ├── 128x128.png │ │ ├── 16x16.png │ │ ├── 38x38.png │ │ ├── 48x48.png │ │ ├── error.png │ │ ├── gray.png │ │ └── scalable.png │ ├── config │ │ ├── webpack.base.ts │ │ ├── webpack.dev.ts │ │ └── webpack.prod.ts │ ├── LICENSE.md │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── components │ │ │ │ ├── FieldTree.tsx │ │ │ │ ├── filter.ts │ │ │ │ ├── LeftPanel.tsx │ │ │ │ ├── RightPanel.tsx │ │ │ │ ├── SearchBox.tsx │ │ │ │ └── Tabs.tsx │ │ │ ├── demo.tsx │ │ │ └── index.tsx │ │ └── extension │ │ ├── backend.ts │ │ ├── background.ts │ │ ├── content.ts │ │ ├── devpanel.tsx │ │ ├── devtools.tsx │ │ ├── inject.ts │ │ ├── manifest.json │ │ ├── popup.tsx │ │ └── views │ │ ├── devpanel.ejs │ │ ├── devtools.ejs │ │ └── popup.ejs │ ├── tsconfig.build.json │ └── tsconfig.json ├── docs │ ├── functions │ │ ├── contributors.ts │ │ └── npm-search.ts │ ├── guide │ │ ├── advanced │ │ │ ├── async.md │ │ │ ├── async.zh-CN.md │ │ │ ├── build.md │ │ │ ├── build.zh-CN.md │ │ │ ├── business-logic.md │ │ │ ├── business-logic.zh-CN.md │ │ │ ├── calculator.md │ │ │ ├── calculator.zh-CN.md │ │ │ ├── controlled.md │ │ │ ├── controlled.zh-CN.md │ │ │ ├── custom.md │ │ │ ├── custom.zh-CN.md │ │ │ ├── destructor.md │ │ │ ├── destructor.zh-CN.md │ │ │ ├── input.less │ │ │ ├── layout.md │ │ │ ├── layout.zh-CN.md │ │ │ ├── linkages.md │ │ │ ├── linkages.zh-CN.md │ │ │ ├── validate.md │ │ │ └── validate.zh-CN.md │ │ ├── contribution.md │ │ ├── contribution.zh-CN.md │ │ ├── form-builder.md │ │ ├── form-builder.zh-CN.md │ │ ├── index.md │ │ ├── index.zh-CN.md │ │ ├── issue-helper.md │ │ ├── issue-helper.zh-CN.md │ │ ├── learn-formily.md │ │ ├── learn-formily.zh-CN.md │ │ ├── quick-start.md │ │ ├── quick-start.zh-CN.md │ │ ├── scenes │ │ │ ├── dialog-drawer.md │ │ │ ├── dialog-drawer.zh-CN.md │ │ │ ├── edit-detail.md │ │ │ ├── edit-detail.zh-CN.md │ │ │ ├── index.less │ │ │ ├── login-register.md │ │ │ ├── login-register.zh-CN.md │ │ │ ├── more.md │ │ │ ├── more.zh-CN.md │ │ │ ├── query-list.md │ │ │ ├── query-list.zh-CN.md │ │ │ ├── step-form.md │ │ │ ├── step-form.zh-CN.md │ │ │ ├── tab-form.md │ │ │ ├── tab-form.zh-CN.md │ │ │ └── VerifyCode.tsx │ │ ├── upgrade.md │ │ └── upgrade.zh-CN.md │ ├── index.md │ ├── index.zh-CN.md │ └── site │ ├── Contributors.less │ ├── Contributors.tsx │ ├── QrCode.less │ ├── QrCode.tsx │ ├── Section.less │ ├── Section.tsx │ └── styles.less ├── global.config.ts ├── jest.config.js ├── lerna.json ├── LICENSE.md ├── package.json ├── packages │ ├── .eslintrc │ ├── antd │ │ ├── __tests__ │ │ │ ├── moment.spec.ts │ │ │ └── sideEffects.spec.ts │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── build-style.ts │ │ ├── create-style.ts │ │ ├── docs │ │ │ ├── components │ │ │ │ ├── ArrayCards.md │ │ │ │ ├── ArrayCards.zh-CN.md │ │ │ │ ├── ArrayCollapse.md │ │ │ │ ├── ArrayCollapse.zh-CN.md │ │ │ │ ├── ArrayItems.md │ │ │ │ ├── ArrayItems.zh-CN.md │ │ │ │ ├── ArrayTable.md │ │ │ │ ├── ArrayTable.zh-CN.md │ │ │ │ ├── ArrayTabs.md │ │ │ │ ├── ArrayTabs.zh-CN.md │ │ │ │ ├── Cascader.md │ │ │ │ ├── Cascader.zh-CN.md │ │ │ │ ├── Checkbox.md │ │ │ │ ├── Checkbox.zh-CN.md │ │ │ │ ├── DatePicker.md │ │ │ │ ├── DatePicker.zh-CN.md │ │ │ │ ├── Editable.md │ │ │ │ ├── Editable.zh-CN.md │ │ │ │ ├── Form.md │ │ │ │ ├── Form.zh-CN.md │ │ │ │ ├── FormButtonGroup.md │ │ │ │ ├── FormButtonGroup.zh-CN.md │ │ │ │ ├── FormCollapse.md │ │ │ │ ├── FormCollapse.zh-CN.md │ │ │ │ ├── FormDialog.md │ │ │ │ ├── FormDialog.zh-CN.md │ │ │ │ ├── FormDrawer.md │ │ │ │ ├── FormDrawer.zh-CN.md │ │ │ │ ├── FormGrid.md │ │ │ │ ├── FormGrid.zh-CN.md │ │ │ │ ├── FormItem.md │ │ │ │ ├── FormItem.zh-CN.md │ │ │ │ ├── FormLayout.md │ │ │ │ ├── FormLayout.zh-CN.md │ │ │ │ ├── FormStep.md │ │ │ │ ├── FormStep.zh-CN.md │ │ │ │ ├── FormTab.md │ │ │ │ ├── FormTab.zh-CN.md │ │ │ │ ├── index.md │ │ │ │ ├── index.zh-CN.md │ │ │ │ ├── Input.md │ │ │ │ ├── Input.zh-CN.md │ │ │ │ ├── NumberPicker.md │ │ │ │ ├── NumberPicker.zh-CN.md │ │ │ │ ├── Password.md │ │ │ │ ├── Password.zh-CN.md │ │ │ │ ├── PreviewText.md │ │ │ │ ├── PreviewText.zh-CN.md │ │ │ │ ├── Radio.md │ │ │ │ ├── Radio.zh-CN.md │ │ │ │ ├── Reset.md │ │ │ │ ├── Reset.zh-CN.md │ │ │ │ ├── Select.md │ │ │ │ ├── Select.zh-CN.md │ │ │ │ ├── SelectTable.md │ │ │ │ ├── SelectTable.zh-CN.md │ │ │ │ ├── Space.md │ │ │ │ ├── Space.zh-CN.md │ │ │ │ ├── Submit.md │ │ │ │ ├── Submit.zh-CN.md │ │ │ │ ├── Switch.md │ │ │ │ ├── Switch.zh-CN.md │ │ │ │ ├── TimePicker.md │ │ │ │ ├── TimePicker.zh-CN.md │ │ │ │ ├── Transfer.md │ │ │ │ ├── Transfer.zh-CN.md │ │ │ │ ├── TreeSelect.md │ │ │ │ ├── TreeSelect.zh-CN.md │ │ │ │ ├── Upload.md │ │ │ │ └── Upload.zh-CN.md │ │ │ ├── index.md │ │ │ └── index.zh-CN.md │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __builtins__ │ │ │ │ ├── hooks │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useClickAway.ts │ │ │ │ │ └── usePrefixCls.ts │ │ │ │ ├── index.ts │ │ │ │ ├── loading.ts │ │ │ │ ├── moment.ts │ │ │ │ ├── pickDataProps.ts │ │ │ │ ├── portal.tsx │ │ │ │ ├── render.ts │ │ │ │ └── sort.tsx │ │ │ ├── array-base │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── array-cards │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── array-collapse │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── array-items │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── array-table │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── array-tabs │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── cascader │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── checkbox │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── date-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── editable │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── form │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── form-button-group │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── form-collapse │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-dialog │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-drawer │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-grid │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── form-item │ │ │ │ ├── animation.less │ │ │ │ ├── grid.less │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── form-layout │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ ├── style.ts │ │ │ │ └── useResponsiveFormLayout.ts │ │ │ ├── form-step │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-tab │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── index.ts │ │ │ ├── input │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── number-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── password │ │ │ │ ├── index.tsx │ │ │ │ ├── PasswordStrength.tsx │ │ │ │ └── style.ts │ │ │ ├── preview-text │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── radio │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ └── style.ts │ │ │ ├── reset │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── select │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── select-table │ │ │ │ ├── index.tsx │ │ │ │ ├── style.less │ │ │ │ ├── style.ts │ │ │ │ ├── useCheckSlackly.tsx │ │ │ │ ├── useFilterOptions.tsx │ │ │ │ ├── useFlatOptions.tsx │ │ │ │ ├── useSize.tsx │ │ │ │ ├── useTitleAddon.tsx │ │ │ │ └── utils.ts │ │ │ ├── space │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── style.less │ │ │ ├── style.ts │ │ │ ├── submit │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── switch │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── time-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── transfer │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── tree-select │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ └── upload │ │ │ ├── index.tsx │ │ │ ├── placeholder.ts │ │ │ └── style.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── benchmark │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ └── index.tsx │ │ ├── template.ejs │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ ├── webpack.base.ts │ │ ├── webpack.dev.ts │ │ └── webpack.prod.ts │ ├── core │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── docs │ │ │ ├── api │ │ │ │ ├── entry │ │ │ │ │ ├── ActionResponse.less │ │ │ │ │ ├── ActionResponse.tsx │ │ │ │ │ ├── createForm.md │ │ │ │ │ ├── createForm.zh-CN.md │ │ │ │ │ ├── FieldEffectHooks.md │ │ │ │ │ ├── FieldEffectHooks.zh-CN.md │ │ │ │ │ ├── FormChecker.md │ │ │ │ │ ├── FormChecker.zh-CN.md │ │ │ │ │ ├── FormEffectHooks.md │ │ │ │ │ ├── FormEffectHooks.zh-CN.md │ │ │ │ │ ├── FormHooksAPI.md │ │ │ │ │ ├── FormHooksAPI.zh-CN.md │ │ │ │ │ ├── FormPath.md │ │ │ │ │ ├── FormPath.zh-CN.md │ │ │ │ │ ├── FormValidatorRegistry.md │ │ │ │ │ └── FormValidatorRegistry.zh-CN.md │ │ │ │ └── models │ │ │ │ ├── ArrayField.md │ │ │ │ ├── ArrayField.zh-CN.md │ │ │ │ ├── Field.md │ │ │ │ ├── Field.zh-CN.md │ │ │ │ ├── Form.md │ │ │ │ ├── Form.zh-CN.md │ │ │ │ ├── ObjectField.md │ │ │ │ ├── ObjectField.zh-CN.md │ │ │ │ ├── Query.md │ │ │ │ ├── Query.zh-CN.md │ │ │ │ ├── VoidField.md │ │ │ │ └── VoidField.zh-CN.md │ │ │ ├── guide │ │ │ │ ├── architecture.md │ │ │ │ ├── architecture.zh-CN.md │ │ │ │ ├── field.md │ │ │ │ ├── field.zh-CN.md │ │ │ │ ├── form.md │ │ │ │ ├── form.zh-CN.md │ │ │ │ ├── index.md │ │ │ │ ├── index.zh-CN.md │ │ │ │ ├── mvvm.md │ │ │ │ ├── mvvm.zh-CN.md │ │ │ │ ├── values.md │ │ │ │ └── values.zh-CN.md │ │ │ ├── index.md │ │ │ └── index.zh-CN.md │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── array.spec.ts │ │ │ │ ├── effects.spec.ts │ │ │ │ ├── externals.spec.ts │ │ │ │ ├── field.spec.ts │ │ │ │ ├── form.spec.ts │ │ │ │ ├── graph.spec.ts │ │ │ │ ├── heart.spec.ts │ │ │ │ ├── internals.spec.ts │ │ │ │ ├── lifecycle.spec.ts │ │ │ │ ├── object.spec.ts │ │ │ │ ├── shared.ts │ │ │ │ └── void.spec.ts │ │ │ ├── effects │ │ │ │ ├── index.ts │ │ │ │ ├── onFieldEffects.ts │ │ │ │ └── onFormEffects.ts │ │ │ ├── global.d.ts │ │ │ ├── index.ts │ │ │ ├── models │ │ │ │ ├── ArrayField.ts │ │ │ │ ├── BaseField.ts │ │ │ │ ├── Field.ts │ │ │ │ ├── Form.ts │ │ │ │ ├── Graph.ts │ │ │ │ ├── Heart.ts │ │ │ │ ├── index.ts │ │ │ │ ├── LifeCycle.ts │ │ │ │ ├── ObjectField.ts │ │ │ │ ├── Query.ts │ │ │ │ ├── types.ts │ │ │ │ └── VoidField.ts │ │ │ ├── shared │ │ │ │ ├── checkers.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── effective.ts │ │ │ │ ├── externals.ts │ │ │ │ └── internals.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── element │ │ ├── .npmignore │ │ ├── build-style.ts │ │ ├── create-style.ts │ │ ├── docs │ │ │ ├── .vuepress │ │ │ │ ├── components │ │ │ │ │ ├── createCodeSandBox.js │ │ │ │ │ ├── dumi-previewer.vue │ │ │ │ │ └── highlight.js │ │ │ │ ├── config.js │ │ │ │ ├── enhanceApp.js │ │ │ │ ├── styles │ │ │ │ │ └── index.styl │ │ │ │ └── util.js │ │ │ ├── demos │ │ │ │ ├── guide │ │ │ │ │ ├── array-cards │ │ │ │ │ │ ├── effects-json-schema.vue │ │ │ │ │ │ ├── effects-markup-schema.vue │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── array-collapse │ │ │ │ │ │ ├── effects-json-schema.vue │ │ │ │ │ │ ├── effects-markup-schema.vue │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── array-items │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── array-table │ │ │ │ │ │ ├── effects-json-schema.vue │ │ │ │ │ │ ├── effects-markup-schema.vue │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── array-tabs │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── cascader │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── checkbox │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── date-picker │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── editable │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── form-button-group.vue │ │ │ │ │ ├── form-collapse │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── form-dialog │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── form-drawer │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── form-grid │ │ │ │ │ │ ├── form.vue │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── native.vue │ │ │ │ │ ├── form-item │ │ │ │ │ │ ├── bordered-none.vue │ │ │ │ │ │ ├── common.vue │ │ │ │ │ │ ├── feedback.vue │ │ │ │ │ │ ├── inset.vue │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ ├── size.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── form-layout │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── form-step │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── form-tab │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ └── markup-schema.vue │ │ │ │ │ ├── form.vue │ │ │ │ │ ├── input │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── input-number │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── password │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── preview-text │ │ │ │ │ │ ├── base.vue │ │ │ │ │ │ └── extend.vue │ │ │ │ │ ├── radio │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── reset │ │ │ │ │ │ ├── base.vue │ │ │ │ │ │ ├── force.vue │ │ │ │ │ │ └── validate.vue │ │ │ │ │ ├── select │ │ │ │ │ │ ├── json-schema-async.vue │ │ │ │ │ │ ├── json-schema-sync.vue │ │ │ │ │ │ ├── markup-schema-async-search.vue │ │ │ │ │ │ ├── markup-schema-async.vue │ │ │ │ │ │ ├── markup-schema-sync.vue │ │ │ │ │ │ ├── template-async.vue │ │ │ │ │ │ └── template-sync.vue │ │ │ │ │ ├── space │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── submit │ │ │ │ │ │ ├── base.vue │ │ │ │ │ │ └── loading.vue │ │ │ │ │ ├── switch │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── time-picker │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ ├── transfer │ │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ │ └── template.vue │ │ │ │ │ └── upload │ │ │ │ │ ├── json-schema.vue │ │ │ │ │ ├── markup-schema.vue │ │ │ │ │ └── template.vue │ │ │ │ └── index.vue │ │ │ ├── guide │ │ │ │ ├── array-cards.md │ │ │ │ ├── array-collapse.md │ │ │ │ ├── array-items.md │ │ │ │ ├── array-table.md │ │ │ │ ├── array-tabs.md │ │ │ │ ├── cascader.md │ │ │ │ ├── checkbox.md │ │ │ │ ├── date-picker.md │ │ │ │ ├── editable.md │ │ │ │ ├── form-button-group.md │ │ │ │ ├── form-collapse.md │ │ │ │ ├── form-dialog.md │ │ │ │ ├── form-drawer.md │ │ │ │ ├── form-grid.md │ │ │ │ ├── form-item.md │ │ │ │ ├── form-layout.md │ │ │ │ ├── form-step.md │ │ │ │ ├── form-tab.md │ │ │ │ ├── form.md │ │ │ │ ├── index.md │ │ │ │ ├── input-number.md │ │ │ │ ├── input.md │ │ │ │ ├── password.md │ │ │ │ ├── preview-text.md │ │ │ │ ├── radio.md │ │ │ │ ├── reset.md │ │ │ │ ├── select.md │ │ │ │ ├── space.md │ │ │ │ ├── submit.md │ │ │ │ ├── switch.md │ │ │ │ ├── time-picker.md │ │ │ │ ├── transfer.md │ │ │ │ └── upload.md │ │ │ └── README.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __builtins__ │ │ │ │ ├── configs │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── shared │ │ │ │ │ ├── create-context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── loading.ts │ │ │ │ │ ├── portal.ts │ │ │ │ │ ├── resolve-component.ts │ │ │ │ │ ├── transform-component.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── styles │ │ │ │ └── common.scss │ │ │ ├── array-base │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── array-cards │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── array-collapse │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── array-items │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── array-table │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── array-tabs │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── cascader │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── checkbox │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── date-picker │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── editable │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── el-form │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── el-form-item │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── form │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── form-button-group │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── form-collapse │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── form-dialog │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── form-drawer │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── form-grid │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── form-item │ │ │ │ ├── animation.scss │ │ │ │ ├── grid.scss │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ ├── style.ts │ │ │ │ └── var.scss │ │ │ ├── form-layout │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ ├── style.ts │ │ │ │ └── useResponsiveFormLayout.ts │ │ │ ├── form-step │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── form-tab │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── index.ts │ │ │ ├── input │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── input-number │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── password │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── preview-text │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── radio │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── reset │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── select │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── space │ │ │ │ ├── index.ts │ │ │ │ ├── style.scss │ │ │ │ └── style.ts │ │ │ ├── style.ts │ │ │ ├── submit │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── switch │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── time-picker │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ ├── transfer │ │ │ │ ├── index.ts │ │ │ │ └── style.ts │ │ │ └── upload │ │ │ ├── index.ts │ │ │ └── style.ts │ │ ├── transformer.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── grid │ │ ├── .npmignore │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── index.ts │ │ │ └── observer.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── json-schema │ │ ├── .npmignore │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── schema.spec.ts.snap │ │ │ │ ├── compiler.spec.ts │ │ │ │ ├── patches.spec.ts │ │ │ │ ├── schema.spec.ts │ │ │ │ ├── server-validate.spec.ts │ │ │ │ ├── shared.spec.ts │ │ │ │ ├── transformer.spec.ts │ │ │ │ └── traverse.spec.ts │ │ │ ├── compiler.ts │ │ │ ├── global.d.ts │ │ │ ├── index.ts │ │ │ ├── patches.ts │ │ │ ├── polyfills │ │ │ │ ├── index.ts │ │ │ │ └── SPECIFICATION_1_0.ts │ │ │ ├── schema.ts │ │ │ ├── shared.ts │ │ │ ├── transformer.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── next │ │ ├── __tests__ │ │ │ ├── moment.spec.ts │ │ │ └── sideEffects.spec.ts │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── build-style.ts │ │ ├── create-style.ts │ │ ├── docs │ │ │ ├── components │ │ │ │ ├── ArrayCards.md │ │ │ │ ├── ArrayCards.zh-CN.md │ │ │ │ ├── ArrayCollapse.md │ │ │ │ ├── ArrayCollapse.zh-CN.md │ │ │ │ ├── ArrayItems.md │ │ │ │ ├── ArrayItems.zh-CN.md │ │ │ │ ├── ArrayTable.md │ │ │ │ ├── ArrayTable.zh-CN.md │ │ │ │ ├── Cascader.md │ │ │ │ ├── Cascader.zh-CN.md │ │ │ │ ├── Checkbox.md │ │ │ │ ├── Checkbox.zh-CN.md │ │ │ │ ├── DatePicker.md │ │ │ │ ├── DatePicker.zh-CN.md │ │ │ │ ├── DatePicker2.md │ │ │ │ ├── DatePicker2.zh-CN.md │ │ │ │ ├── Editable.md │ │ │ │ ├── Editable.zh-CN.md │ │ │ │ ├── Form.md │ │ │ │ ├── Form.zh-CN.md │ │ │ │ ├── FormButtonGroup.md │ │ │ │ ├── FormButtonGroup.zh-CN.md │ │ │ │ ├── FormCollapse.md │ │ │ │ ├── FormCollapse.zh-CN.md │ │ │ │ ├── FormDialog.md │ │ │ │ ├── FormDialog.zh-CN.md │ │ │ │ ├── FormDrawer.md │ │ │ │ ├── FormDrawer.zh-CN.md │ │ │ │ ├── FormGrid.md │ │ │ │ ├── FormGrid.zh-CN.md │ │ │ │ ├── FormItem.md │ │ │ │ ├── FormItem.zh-CN.md │ │ │ │ ├── FormLayout.md │ │ │ │ ├── FormLayout.zh-CN.md │ │ │ │ ├── FormStep.md │ │ │ │ ├── FormStep.zh-CN.md │ │ │ │ ├── FormTab.md │ │ │ │ ├── FormTab.zh-CN.md │ │ │ │ ├── index.md │ │ │ │ ├── index.zh-CN.md │ │ │ │ ├── Input.md │ │ │ │ ├── Input.zh-CN.md │ │ │ │ ├── NumberPicker.md │ │ │ │ ├── NumberPicker.zh-CN.md │ │ │ │ ├── Password.md │ │ │ │ ├── Password.zh-CN.md │ │ │ │ ├── PreviewText.md │ │ │ │ ├── PreviewText.zh-CN.md │ │ │ │ ├── Radio.md │ │ │ │ ├── Radio.zh-CN.md │ │ │ │ ├── Reset.md │ │ │ │ ├── Reset.zh-CN.md │ │ │ │ ├── Select.md │ │ │ │ ├── Select.zh-CN.md │ │ │ │ ├── SelectTable.md │ │ │ │ ├── SelectTable.zh-CN.md │ │ │ │ ├── Space.md │ │ │ │ ├── Space.zh-CN.md │ │ │ │ ├── Submit.md │ │ │ │ ├── Submit.zh-CN.md │ │ │ │ ├── Switch.md │ │ │ │ ├── Switch.zh-CN.md │ │ │ │ ├── TimePicker.md │ │ │ │ ├── TimePicker.zh-CN.md │ │ │ │ ├── TimePicker2.md │ │ │ │ ├── TimePicker2.zh-CN.md │ │ │ │ ├── Transfer.md │ │ │ │ ├── Transfer.zh-CN.md │ │ │ │ ├── TreeSelect.md │ │ │ │ ├── TreeSelect.zh-CN.md │ │ │ │ ├── Upload.md │ │ │ │ └── Upload.zh-CN.md │ │ │ ├── index.md │ │ │ └── index.zh-CN.md │ │ ├── LESENCE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __builtins__ │ │ │ │ ├── empty.tsx │ │ │ │ ├── hooks │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useClickAway.ts │ │ │ │ │ └── usePrefixCls.ts │ │ │ │ ├── icons.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── loading.ts │ │ │ │ ├── mapSize.ts │ │ │ │ ├── mapStatus.ts │ │ │ │ ├── moment.ts │ │ │ │ ├── pickDataProps.ts │ │ │ │ ├── portal.tsx │ │ │ │ ├── render.ts │ │ │ │ └── toArray.ts │ │ │ ├── array-base │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── array-cards │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── array-collapse │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── array-items │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── array-table │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── cascader │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── checkbox │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── date-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── date-picker2 │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── editable │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── form │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── form-button-group │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── form-collapse │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-dialog │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-drawer │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-grid │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── form-item │ │ │ │ ├── animation.scss │ │ │ │ ├── grid.scss │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ ├── scss │ │ │ │ │ └── variable.scss │ │ │ │ └── style.ts │ │ │ ├── form-layout │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ ├── style.ts │ │ │ │ └── useResponsiveFormLayout.ts │ │ │ ├── form-step │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── form-tab │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── index.ts │ │ │ ├── input │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── main.scss │ │ │ ├── number-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── password │ │ │ │ ├── index.tsx │ │ │ │ ├── PasswordStrength.tsx │ │ │ │ └── style.ts │ │ │ ├── preview-text │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── radio │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── reset │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── select │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── select-table │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ ├── style.ts │ │ │ │ ├── useCheckSlackly.tsx │ │ │ │ ├── useFilterOptions.tsx │ │ │ │ ├── useFlatOptions.tsx │ │ │ │ ├── useSize.tsx │ │ │ │ ├── useTitleAddon.tsx │ │ │ │ └── utils.ts │ │ │ ├── space │ │ │ │ ├── index.tsx │ │ │ │ ├── main.scss │ │ │ │ └── style.ts │ │ │ ├── style.ts │ │ │ ├── submit │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── switch │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── time-picker │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── time-picker2 │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── transfer │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── tree-select │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ └── upload │ │ │ ├── index.tsx │ │ │ ├── main.scss │ │ │ ├── placeholder.ts │ │ │ └── style.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── path │ │ ├── .npmignore │ │ ├── benchmark.ts │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── accessor.spec.ts │ │ │ │ ├── basic.spec.ts │ │ │ │ ├── match.spec.ts │ │ │ │ ├── parser.spec.ts │ │ │ │ └── share.spec.ts │ │ │ ├── contexts.ts │ │ │ ├── destructor.ts │ │ │ ├── index.ts │ │ │ ├── matcher.ts │ │ │ ├── parser.ts │ │ │ ├── shared.ts │ │ │ ├── tokenizer.ts │ │ │ ├── tokens.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── react │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── docs │ │ │ ├── api │ │ │ │ ├── components │ │ │ │ │ ├── ArrayField.md │ │ │ │ │ ├── ArrayField.zh-CN.md │ │ │ │ │ ├── ExpressionScope.md │ │ │ │ │ ├── ExpressionScope.zh-CN.md │ │ │ │ │ ├── Field.md │ │ │ │ │ ├── Field.zh-CN.md │ │ │ │ │ ├── FormConsumer.md │ │ │ │ │ ├── FormConsumer.zh-CN.md │ │ │ │ │ ├── FormProvider.md │ │ │ │ │ ├── FormProvider.zh-CN.md │ │ │ │ │ ├── ObjectField.md │ │ │ │ │ ├── ObjectField.zh-CN.md │ │ │ │ │ ├── RecordScope.md │ │ │ │ │ ├── RecordScope.zh-CN.md │ │ │ │ │ ├── RecordsScope.md │ │ │ │ │ ├── RecordsScope.zh-CN.md │ │ │ │ │ ├── RecursionField.md │ │ │ │ │ ├── RecursionField.zh-CN.md │ │ │ │ │ ├── SchemaField.md │ │ │ │ │ ├── SchemaField.zh-CN.md │ │ │ │ │ ├── VoidField.md │ │ │ │ │ └── VoidField.zh-CN.md │ │ │ │ ├── hooks │ │ │ │ │ ├── useExpressionScope.md │ │ │ │ │ ├── useExpressionScope.zh-CN.md │ │ │ │ │ ├── useField.md │ │ │ │ │ ├── useField.zh-CN.md │ │ │ │ │ ├── useFieldSchema.md │ │ │ │ │ ├── useFieldSchema.zh-CN.md │ │ │ │ │ ├── useForm.md │ │ │ │ │ ├── useForm.zh-CN.md │ │ │ │ │ ├── useFormEffects.md │ │ │ │ │ ├── useFormEffects.zh-CN.md │ │ │ │ │ ├── useParentForm.md │ │ │ │ │ └── useParentForm.zh-CN.md │ │ │ │ └── shared │ │ │ │ ├── connect.md │ │ │ │ ├── connect.zh-CN.md │ │ │ │ ├── context.md │ │ │ │ ├── context.zh-CN.md │ │ │ │ ├── mapProps.md │ │ │ │ ├── mapProps.zh-CN.md │ │ │ │ ├── mapReadPretty.md │ │ │ │ ├── mapReadPretty.zh-CN.md │ │ │ │ ├── observer.md │ │ │ │ ├── observer.zh-CN.md │ │ │ │ ├── Schema.md │ │ │ │ └── Schema.zh-CN.md │ │ │ ├── guide │ │ │ │ ├── architecture.md │ │ │ │ ├── architecture.zh-CN.md │ │ │ │ ├── concept.md │ │ │ │ ├── concept.zh-CN.md │ │ │ │ ├── index.md │ │ │ │ └── index.zh-CN.md │ │ │ ├── index.md │ │ │ └── index.zh-CN.md │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── expression.spec.tsx │ │ │ │ ├── field.spec.tsx │ │ │ │ ├── form.spec.tsx │ │ │ │ ├── schema.json.spec.tsx │ │ │ │ ├── schema.markup.spec.tsx │ │ │ │ └── shared.tsx │ │ │ ├── components │ │ │ │ ├── ArrayField.tsx │ │ │ │ ├── ExpressionScope.tsx │ │ │ │ ├── Field.tsx │ │ │ │ ├── FormConsumer.tsx │ │ │ │ ├── FormProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── ObjectField.tsx │ │ │ │ ├── ReactiveField.tsx │ │ │ │ ├── RecordScope.tsx │ │ │ │ ├── RecordsScope.tsx │ │ │ │ ├── RecursionField.tsx │ │ │ │ ├── SchemaField.tsx │ │ │ │ └── VoidField.tsx │ │ │ ├── global.d.ts │ │ │ ├── hooks │ │ │ │ ├── index.ts │ │ │ │ ├── useAttach.ts │ │ │ │ ├── useExpressionScope.ts │ │ │ │ ├── useField.ts │ │ │ │ ├── useFieldSchema.ts │ │ │ │ ├── useForm.ts │ │ │ │ ├── useFormEffects.ts │ │ │ │ └── useParentForm.ts │ │ │ ├── index.ts │ │ │ ├── shared │ │ │ │ ├── connect.ts │ │ │ │ ├── context.ts │ │ │ │ ├── index.ts │ │ │ │ └── render.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── reactive │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── benchmark.ts │ │ ├── docs │ │ │ ├── api │ │ │ │ ├── action.md │ │ │ │ ├── action.zh-CN.md │ │ │ │ ├── autorun.md │ │ │ │ ├── autorun.zh-CN.md │ │ │ │ ├── batch.md │ │ │ │ ├── batch.zh-CN.md │ │ │ │ ├── define.md │ │ │ │ ├── define.zh-CN.md │ │ │ │ ├── hasCollected.md │ │ │ │ ├── hasCollected.zh-CN.md │ │ │ │ ├── markObservable.md │ │ │ │ ├── markObservable.zh-CN.md │ │ │ │ ├── markRaw.md │ │ │ │ ├── markRaw.zh-CN.md │ │ │ │ ├── model.md │ │ │ │ ├── model.zh-CN.md │ │ │ │ ├── observable.md │ │ │ │ ├── observable.zh-CN.md │ │ │ │ ├── observe.md │ │ │ │ ├── observe.zh-CN.md │ │ │ │ ├── raw.md │ │ │ │ ├── raw.zh-CN.md │ │ │ │ ├── react │ │ │ │ │ ├── observer.md │ │ │ │ │ └── observer.zh-CN.md │ │ │ │ ├── reaction.md │ │ │ │ ├── reaction.zh-CN.md │ │ │ │ ├── toJS.md │ │ │ │ ├── toJS.zh-CN.md │ │ │ │ ├── tracker.md │ │ │ │ ├── tracker.zh-CN.md │ │ │ │ ├── typeChecker.md │ │ │ │ ├── typeChecker.zh-CN.md │ │ │ │ ├── untracked.md │ │ │ │ ├── untracked.zh-CN.md │ │ │ │ └── vue │ │ │ │ ├── observer.md │ │ │ │ └── observer.zh-CN.md │ │ │ ├── guide │ │ │ │ ├── best-practice.md │ │ │ │ ├── best-practice.zh-CN.md │ │ │ │ ├── concept.md │ │ │ │ ├── concept.zh-CN.md │ │ │ │ ├── index.md │ │ │ │ └── index.zh-CN.md │ │ │ ├── index.md │ │ │ └── index.zh-CN.md │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── action.spec.ts │ │ │ │ ├── annotations.spec.ts │ │ │ │ ├── array.spec.ts │ │ │ │ ├── autorun.spec.ts │ │ │ │ ├── batch.spec.ts │ │ │ │ ├── collections-map.spec.ts │ │ │ │ ├── collections-set.spec.ts │ │ │ │ ├── collections-weakmap.spec.ts │ │ │ │ ├── collections-weakset.spec.ts │ │ │ │ ├── define.spec.ts │ │ │ │ ├── externals.spec.ts │ │ │ │ ├── hasCollected.spec.ts │ │ │ │ ├── observable.spec.ts │ │ │ │ ├── observe.spec.ts │ │ │ │ ├── tracker.spec.ts │ │ │ │ └── untracked.spec.ts │ │ │ ├── action.ts │ │ │ ├── annotations │ │ │ │ ├── box.ts │ │ │ │ ├── computed.ts │ │ │ │ ├── index.ts │ │ │ │ ├── observable.ts │ │ │ │ ├── ref.ts │ │ │ │ └── shallow.ts │ │ │ ├── array.ts │ │ │ ├── autorun.ts │ │ │ ├── batch.ts │ │ │ ├── checkers.ts │ │ │ ├── environment.ts │ │ │ ├── externals.ts │ │ │ ├── global.d.ts │ │ │ ├── handlers.ts │ │ │ ├── index.ts │ │ │ ├── internals.ts │ │ │ ├── model.ts │ │ │ ├── observable.ts │ │ │ ├── observe.ts │ │ │ ├── reaction.ts │ │ │ ├── tracker.ts │ │ │ ├── tree.ts │ │ │ ├── types.ts │ │ │ └── untracked.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── reactive-react │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── hooks │ │ │ │ ├── index.ts │ │ │ │ ├── useCompatEffect.ts │ │ │ │ ├── useCompatFactory.ts │ │ │ │ ├── useDidUpdate.ts │ │ │ │ ├── useForceUpdate.ts │ │ │ │ ├── useLayoutEffect.ts │ │ │ │ └── useObserver.ts │ │ │ ├── index.ts │ │ │ ├── observer.ts │ │ │ ├── shared │ │ │ │ ├── gc.ts │ │ │ │ ├── global.ts │ │ │ │ ├── immediate.ts │ │ │ │ └── index.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── reactive-test-cases-for-react18 │ │ ├── .npmignore │ │ ├── .umirc.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.js │ │ │ └── MySlowList.js │ │ ├── template.ejs │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ ├── webpack.base.ts │ │ ├── webpack.dev.ts │ │ └── webpack.prod.ts │ ├── reactive-vue │ │ ├── .npmignore │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ └── observer.spec.ts │ │ │ ├── hooks │ │ │ │ ├── index.ts │ │ │ │ └── useObserver.ts │ │ │ ├── index.ts │ │ │ ├── observer │ │ │ │ ├── collectData.ts │ │ │ │ ├── index.ts │ │ │ │ ├── observerInVue2.ts │ │ │ │ └── observerInVue3.ts │ │ │ └── types.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── shared │ │ ├── .npmignore │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ └── index.spec.ts │ │ │ ├── array.ts │ │ │ ├── case.ts │ │ │ ├── checkers.ts │ │ │ ├── clone.ts │ │ │ ├── compare.ts │ │ │ ├── defaults.ts │ │ │ ├── deprecate.ts │ │ │ ├── global.ts │ │ │ ├── index.ts │ │ │ ├── instanceof.ts │ │ │ ├── isEmpty.ts │ │ │ ├── merge.ts │ │ │ ├── middleware.ts │ │ │ ├── path.ts │ │ │ ├── string.ts │ │ │ ├── subscribable.ts │ │ │ └── uid.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── validator │ │ ├── .npmignore │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── rollup.config.js │ │ ├── src │ │ │ ├── __tests__ │ │ │ │ ├── parser.spec.ts │ │ │ │ ├── registry.spec.ts │ │ │ │ └── validator.spec.ts │ │ │ ├── formats.ts │ │ │ ├── index.ts │ │ │ ├── locale.ts │ │ │ ├── parser.ts │ │ │ ├── registry.ts │ │ │ ├── rules.ts │ │ │ ├── template.ts │ │ │ ├── types.ts │ │ │ └── validator.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ └── vue │ ├── .npmignore │ ├── bin │ │ ├── formily-vue-fix.js │ │ └── formily-vue-switch.js │ ├── docs │ │ ├── .vuepress │ │ │ ├── components │ │ │ │ ├── createCodeSandBox.js │ │ │ │ ├── dumi-previewer.vue │ │ │ │ └── highlight.js │ │ │ ├── config.js │ │ │ ├── enhanceApp.js │ │ │ └── styles │ │ │ └── index.styl │ │ ├── api │ │ │ ├── components │ │ │ │ ├── array-field.md │ │ │ │ ├── expression-scope.md │ │ │ │ ├── field.md │ │ │ │ ├── form-consumer.md │ │ │ │ ├── form-provider.md │ │ │ │ ├── object-field.md │ │ │ │ ├── recursion-field-with-component.md │ │ │ │ ├── recursion-field.md │ │ │ │ ├── schema-field-with-schema.md │ │ │ │ ├── schema-field.md │ │ │ │ └── void-field.md │ │ │ ├── hooks │ │ │ │ ├── use-field-schema.md │ │ │ │ ├── use-field.md │ │ │ │ ├── use-form-effects.md │ │ │ │ ├── use-form.md │ │ │ │ └── use-parent-form.md │ │ │ └── shared │ │ │ ├── connect.md │ │ │ ├── injections.md │ │ │ ├── map-props.md │ │ │ ├── map-read-pretty.md │ │ │ ├── observer.md │ │ │ └── schema.md │ │ ├── demos │ │ │ ├── api │ │ │ │ ├── components │ │ │ │ │ ├── array-field.vue │ │ │ │ │ ├── expression-scope.vue │ │ │ │ │ ├── field.vue │ │ │ │ │ ├── form-consumer.vue │ │ │ │ │ ├── form-provider.vue │ │ │ │ │ ├── object-field.vue │ │ │ │ │ ├── recursion-field-with-component.vue │ │ │ │ │ ├── recursion-field.vue │ │ │ │ │ ├── schema-field-with-schema.vue │ │ │ │ │ ├── schema-field.vue │ │ │ │ │ └── void-field.vue │ │ │ │ ├── hooks │ │ │ │ │ ├── use-field-schema.vue │ │ │ │ │ ├── use-field.vue │ │ │ │ │ ├── use-form-effects.vue │ │ │ │ │ ├── use-form.vue │ │ │ │ │ └── use-parent-form.vue │ │ │ │ └── shared │ │ │ │ ├── connect.vue │ │ │ │ ├── map-props.vue │ │ │ │ ├── map-read-pretty.vue │ │ │ │ └── observer.vue │ │ │ ├── index.vue │ │ │ └── questions │ │ │ ├── default-slot.vue │ │ │ ├── events.vue │ │ │ ├── named-slot.vue │ │ │ └── scoped-slot.vue │ │ ├── guide │ │ │ ├── architecture.md │ │ │ ├── concept.md │ │ │ └── README.md │ │ ├── questions │ │ │ └── README.md │ │ └── README.md │ ├── package.json │ ├── README.md │ ├── rollup.config.js │ ├── scripts │ │ ├── postinstall.js │ │ ├── switch-cli.js │ │ └── utils.js │ ├── src │ │ ├── __tests__ │ │ │ ├── expression.scope.spec.ts │ │ │ ├── field.spec.ts │ │ │ ├── form.spec.ts │ │ │ ├── schema.json.spec.ts │ │ │ ├── schema.markup.spec.ts │ │ │ ├── shared.spec.ts │ │ │ └── utils.spec.ts │ │ ├── components │ │ │ ├── ArrayField.ts │ │ │ ├── ExpressionScope.ts │ │ │ ├── Field.ts │ │ │ ├── FormConsumer.ts │ │ │ ├── FormProvider.ts │ │ │ ├── index.ts │ │ │ ├── ObjectField.ts │ │ │ ├── ReactiveField.ts │ │ │ ├── RecursionField.ts │ │ │ ├── SchemaField.ts │ │ │ └── VoidField.ts │ │ ├── global.d.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useAttach.ts │ │ │ ├── useField.ts │ │ │ ├── useFieldSchema.ts │ │ │ ├── useForm.ts │ │ │ ├── useFormEffects.ts │ │ │ ├── useInjectionCleaner.ts │ │ │ └── useParentForm.ts │ │ ├── index.ts │ │ ├── shared │ │ │ ├── connect.ts │ │ │ ├── context.ts │ │ │ ├── createForm.ts │ │ │ ├── fragment.ts │ │ │ ├── h.ts │ │ │ └── index.ts │ │ ├── types │ │ │ └── index.ts │ │ ├── utils │ │ │ ├── formatVNodeData.ts │ │ │ ├── getFieldProps.ts │ │ │ ├── getRawComponent.ts │ │ │ └── resolveSchemaProps.ts │ │ └── vue2-components.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── tsconfig.types.json ├── README.md ├── README.zh-cn.md ├── scripts │ ├── build-style │ │ ├── buildAllStyles.ts │ │ ├── copy.ts │ │ ├── helper.ts │ │ └── index.ts │ └── rollup.base.js ├── tsconfig.build.json ├── tsconfig.jest.json ├── tsconfig.json └── yarn.lock ``` # Files -------------------------------------------------------------------------------- /packages/antd/docs/components/SelectTable.md: -------------------------------------------------------------------------------- ```markdown 1 | # SelectTable 2 | 3 | > Optional table components 4 | 5 | ## Markup Schema single case 6 | 7 | ```tsx 8 | import React from 'react' 9 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 10 | import { createForm } from '@formily/core' 11 | import { FormProvider, createSchemaField } from '@formily/react' 12 | 13 | const SchemaField = createSchemaField({ 14 | components: { 15 | FormItem, 16 | SelectTable, 17 | }, 18 | }) 19 | 20 | const form = createForm() 21 | 22 | export default () => { 23 | return ( 24 | <FormProvider form={form}> 25 | <SchemaField> 26 | <SchemaField.Object 27 | type="string" 28 | name="selectTable" 29 | x-decorator="FormItem" 30 | x-component="SelectTable" 31 | x-component-props={{ 32 | bordered: false, 33 | mode: 'single', 34 | }} 35 | enum={[ 36 | { key: '1', name: 'Title-1', description: 'description-1' }, 37 | { key: '2', name: 'Title-2', description: 'description-2' }, 38 | ]} 39 | > 40 | <SchemaField.Void 41 | name="name" 42 | title="Title" 43 | x-component="SelectTable.Column" 44 | /> 45 | <SchemaField.Void 46 | name="description" 47 | title="Description" 48 | x-component="SelectTable.Column" 49 | /> 50 | </SchemaField.Object> 51 | </SchemaField> 52 | <FormButtonGroup.FormItem> 53 | <Submit onSubmit={console.log}>Submit</Submit> 54 | </FormButtonGroup.FormItem> 55 | </FormProvider> 56 | ) 57 | } 58 | ``` 59 | 60 | ## Markup Schema filter case 61 | 62 | ```tsx 63 | import React from 'react' 64 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 65 | import { createForm } from '@formily/core' 66 | import { FormProvider, createSchemaField } from '@formily/react' 67 | 68 | const SchemaField = createSchemaField({ 69 | components: { 70 | FormItem, 71 | SelectTable, 72 | }, 73 | }) 74 | 75 | const form = createForm() 76 | 77 | export default () => { 78 | return ( 79 | <FormProvider form={form}> 80 | <SchemaField> 81 | <SchemaField.Array 82 | type="array" 83 | name="selectTable" 84 | x-decorator="FormItem" 85 | x-component="SelectTable" 86 | x-component-props={{ 87 | bordered: false, 88 | showSearch: true, 89 | optionAsValue: true, 90 | }} 91 | enum={[ 92 | { key: '1', name: 'Title-1', description: 'description-1' }, 93 | { key: '2', name: 'Title-2', description: 'description-2' }, 94 | ]} 95 | > 96 | <SchemaField.Object> 97 | <SchemaField.Void 98 | name="name" 99 | title="Title" 100 | x-component="SelectTable.Column" 101 | /> 102 | <SchemaField.Void 103 | name="description" 104 | title="Description" 105 | x-component="SelectTable.Column" 106 | /> 107 | </SchemaField.Object> 108 | </SchemaField.Array> 109 | </SchemaField> 110 | <FormButtonGroup.FormItem> 111 | <Submit onSubmit={console.log}>Submit</Submit> 112 | </FormButtonGroup.FormItem> 113 | </FormProvider> 114 | ) 115 | } 116 | ``` 117 | 118 | ## Markup Schema async data source case 119 | 120 | ```tsx 121 | import React from 'react' 122 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 123 | import { createForm } from '@formily/core' 124 | import { FormProvider, createSchemaField } from '@formily/react' 125 | 126 | const SchemaField = createSchemaField({ 127 | components: { 128 | FormItem, 129 | SelectTable, 130 | }, 131 | }) 132 | 133 | const form = createForm() 134 | 135 | export default () => { 136 | const onSearch = (value) => { 137 | const field = form.query('selectTable').take() 138 | field.loading = true 139 | setTimeout(() => { 140 | field.setState({ 141 | dataSource: [ 142 | { 143 | key: '3', 144 | name: 'AAA' + value, 145 | description: 'aaa', 146 | }, 147 | { 148 | key: '4', 149 | name: 'BBB' + value, 150 | description: 'bbb', 151 | }, 152 | ], 153 | loading: false, 154 | }) 155 | }, 1500) 156 | } 157 | 158 | return ( 159 | <FormProvider form={form}> 160 | <SchemaField> 161 | <SchemaField.Object 162 | type="object" 163 | name="selectTable" 164 | x-decorator="FormItem" 165 | x-component="SelectTable" 166 | x-component-props={{ 167 | showSearch: true, 168 | filterOption: false, 169 | onSearch, 170 | }} 171 | enum={[ 172 | { key: '1', name: 'title-1', description: 'description-1' }, 173 | { key: '2', name: 'title-2', description: 'description-2' }, 174 | ]} 175 | > 176 | <SchemaField.Void 177 | name="name" 178 | title="Title" 179 | x-component="SelectTable.Column" 180 | /> 181 | <SchemaField.Void 182 | name="description" 183 | title="Description" 184 | x-component="SelectTable.Column" 185 | /> 186 | </SchemaField.Object> 187 | </SchemaField> 188 | <FormButtonGroup.FormItem> 189 | <Submit onSubmit={console.log}>Submit</Submit> 190 | </FormButtonGroup.FormItem> 191 | </FormProvider> 192 | ) 193 | } 194 | ``` 195 | 196 | ## Markup Schema read-pretty case 197 | 198 | ```tsx 199 | import React from 'react' 200 | import { 201 | Form, 202 | FormItem, 203 | FormButtonGroup, 204 | Submit, 205 | SelectTable, 206 | } from '@formily/antd' 207 | import { createForm } from '@formily/core' 208 | import { createSchemaField } from '@formily/react' 209 | 210 | const SchemaField = createSchemaField({ 211 | components: { 212 | FormItem, 213 | SelectTable, 214 | }, 215 | }) 216 | 217 | const form = createForm() 218 | 219 | export default () => { 220 | return ( 221 | <Form form={form} layout="vertical"> 222 | <SchemaField> 223 | <SchemaField.Object 224 | title="single" 225 | type="string" 226 | name="selectTable1" 227 | x-decorator="FormItem" 228 | x-component="SelectTable" 229 | x-component-props={{ 230 | mode: 'single', 231 | }} 232 | default="1" 233 | enum={[ 234 | { key: '1', name: 'title-1', description: 'description-1' }, 235 | { key: '2', name: 'Title-2', description: 'description-2' }, 236 | ]} 237 | x-read-pretty={true} 238 | > 239 | <SchemaField.Void 240 | name="name" 241 | title="Title" 242 | x-component="SelectTable.Column" 243 | /> 244 | <SchemaField.Void 245 | name="description" 246 | title="Description" 247 | x-component="SelectTable.Column" 248 | /> 249 | </SchemaField.Object> 250 | <SchemaField.Object 251 | title="single + optionAsValue" 252 | type="string" 253 | name="selectTable2" 254 | x-decorator="FormItem" 255 | x-component="SelectTable" 256 | x-component-props={{ 257 | mode: 'single', 258 | optionAsValue: true, 259 | }} 260 | default={{ key: '1', name: 'Title1', description: 'Description1' }} 261 | enum={[ 262 | { key: '1', name: 'title-1', description: 'description-1' }, 263 | { key: '2', name: 'Title-2', description: 'description-2' }, 264 | ]} 265 | x-read-pretty={true} 266 | > 267 | <SchemaField.Void 268 | name="name" 269 | title="Title" 270 | x-component="SelectTable.Column" 271 | /> 272 | <SchemaField.Void 273 | name="description" 274 | title="Description" 275 | x-component="SelectTable.Column" 276 | /> 277 | </SchemaField.Object> 278 | <SchemaField.Array 279 | title="multiple" 280 | type="array" 281 | name="selectTable3" 282 | x-decorator="FormItem" 283 | x-component="SelectTable" 284 | default={['1', '3']} 285 | enum={[ 286 | { key: '1', name: 'title-1', description: 'description-1' }, 287 | { key: '2', name: 'Title-2', description: 'description-2' }, 288 | { key: '3', name: 'title-3', description: 'description-3' }, 289 | ]} 290 | x-read-pretty={true} 291 | > 292 | <SchemaField.Object> 293 | <SchemaField.Void 294 | name="name" 295 | title="Title" 296 | x-component="SelectTable.Column" 297 | /> 298 | <SchemaField.Void 299 | name="description" 300 | title="Description" 301 | x-component="SelectTable.Column" 302 | /> 303 | </SchemaField.Object> 304 | </SchemaField.Array> 305 | <SchemaField.Array 306 | title="multiple + optionAsValue" 307 | type="array" 308 | name="selectTable4" 309 | x-decorator="FormItem" 310 | x-component="SelectTable" 311 | x-component-props={{ 312 | optionAsValue: true, 313 | }} 314 | default={[ 315 | { key: '1', name: 'title-1', description: 'description-1' }, 316 | { key: '3', name: 'title-3', description: 'description-3' }, 317 | ]} 318 | enum={[ 319 | { key: '1', name: 'title-1', description: 'description-1' }, 320 | { key: '2', name: 'Title-2', description: 'description-2' }, 321 | { key: '3', name: 'title-3', description: 'description-3' }, 322 | ]} 323 | x-read-pretty={true} 324 | > 325 | <SchemaField.Object> 326 | <SchemaField.Void 327 | name="name" 328 | title="Title" 329 | x-component="SelectTable.Column" 330 | /> 331 | <SchemaField.Void 332 | name="description" 333 | title="Description" 334 | x-component="SelectTable.Column" 335 | /> 336 | </SchemaField.Object> 337 | </SchemaField.Array> 338 | </SchemaField> 339 | <FormButtonGroup.FormItem> 340 | <Submit onSubmit={console.log}>Submit</Submit> 341 | </FormButtonGroup.FormItem> 342 | </Form> 343 | ) 344 | } 345 | ``` 346 | 347 | ## JSON Schema multiple case 348 | 349 | ```tsx 350 | import React from 'react' 351 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 352 | import { createForm } from '@formily/core' 353 | import { FormProvider, createSchemaField } from '@formily/react' 354 | 355 | const SchemaField = createSchemaField({ 356 | components: { 357 | SelectTable, 358 | FormItem, 359 | }, 360 | }) 361 | 362 | const form = createForm() 363 | 364 | const schema = { 365 | type: 'object', 366 | properties: { 367 | selectTable: { 368 | type: 'array', 369 | 'x-decorator': 'FormItem', 370 | 'x-component': 'SelectTable', 371 | 'x-component-props': { 372 | bordered: false, 373 | mode: 'multiple', 374 | }, 375 | enum: [ 376 | { key: '1', name: 'Title-1', description: 'description-1' }, 377 | { key: '2', name: 'Title-2', description: 'description-2' }, 378 | ], 379 | properties: { 380 | name: { 381 | title: 'Title', 382 | type: 'string', 383 | 'x-component': 'SelectTable.Column', 384 | 'x-component-props': { 385 | width: '40%', 386 | }, 387 | }, 388 | description: { 389 | title: 'Description', 390 | type: 'string', 391 | 'x-component': 'SelectTable.Column', 392 | 'x-component-props': { 393 | width: '60%', 394 | }, 395 | }, 396 | }, 397 | }, 398 | }, 399 | } 400 | 401 | export default () => ( 402 | <FormProvider form={form}> 403 | <SchemaField schema={schema} /> 404 | <FormButtonGroup> 405 | <Submit onSubmit={console.log}>Submit</Submit> 406 | </FormButtonGroup> 407 | </FormProvider> 408 | ) 409 | ``` 410 | 411 | ## JSON Schema custom filter case 412 | 413 | ```tsx 414 | import React from 'react' 415 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 416 | import { createForm } from '@formily/core' 417 | import { FormProvider, createSchemaField } from '@formily/react' 418 | 419 | const SchemaField = createSchemaField({ 420 | components: { 421 | SelectTable, 422 | FormItem, 423 | }, 424 | }) 425 | 426 | const form = createForm() 427 | 428 | const schema = { 429 | type: 'object', 430 | properties: { 431 | selectTable: { 432 | type: 'array', 433 | 'x-decorator': 'FormItem', 434 | 'x-component': 'SelectTable', 435 | 'x-component-props': { 436 | bordered: false, 437 | showSearch: true, 438 | primaryKey: 'key', 439 | isTree: true, 440 | filterOption: (input, option) => 441 | option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0, 442 | filterSort: (optionA, optionB) => 443 | optionA.description 444 | .toLowerCase() 445 | .localeCompare(optionB.description.toLowerCase()), 446 | optionAsValue: true, 447 | rowSelection: { 448 | checkStrictly: false, 449 | }, 450 | }, 451 | enum: [ 452 | { key: '1', name: 'title-1', description: 'A-description' }, 453 | { 454 | key: '2', 455 | name: 'title-2', 456 | description: 'X-description', 457 | children: [ 458 | { 459 | key: '2-1', 460 | name: 'title2-1', 461 | description: 'Y-description', 462 | children: [ 463 | { 464 | key: '2-1-1', 465 | name: 'title-2-1-1', 466 | description: 'Z-description', 467 | }, 468 | ], 469 | }, 470 | { 471 | key: '2-2', 472 | name: 'title2-2', 473 | description: 'YY-description', 474 | }, 475 | ], 476 | }, 477 | { key: '3', name: 'title-3', description: 'C-description' }, 478 | ], 479 | properties: { 480 | name: { 481 | title: 'Title', 482 | type: 'string', 483 | 'x-component': 'SelectTable.Column', 484 | 'x-component-props': { 485 | width: '40%', 486 | }, 487 | }, 488 | description: { 489 | title: 'Description', 490 | type: 'string', 491 | 'x-component': 'SelectTable.Column', 492 | 'x-component-props': { 493 | width: '60%', 494 | }, 495 | }, 496 | }, 497 | }, 498 | }, 499 | } 500 | 501 | export default () => ( 502 | <FormProvider form={form}> 503 | <SchemaField schema={schema} /> 504 | <FormButtonGroup> 505 | <Submit onSubmit={console.log}>Submit</Submit> 506 | </FormButtonGroup> 507 | </FormProvider> 508 | ) 509 | ``` 510 | 511 | ## JSON Schema async data source case 512 | 513 | ```tsx 514 | import React from 'react' 515 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 516 | import { createForm } from '@formily/core' 517 | import { FormProvider, createSchemaField } from '@formily/react' 518 | 519 | const SchemaField = createSchemaField({ 520 | components: { 521 | SelectTable, 522 | FormItem, 523 | }, 524 | }) 525 | 526 | const loadData = async (value) => { 527 | return new Promise((resolve) => { 528 | setTimeout(() => { 529 | resolve([ 530 | { key: '3', name: 'AAA' + value, description: 'aaa' }, 531 | { key: '4', name: 'BBB' + value, description: 'bbb' }, 532 | ]) 533 | }, 1500) 534 | }) 535 | } 536 | 537 | const useAsyncDataSource = (service, field) => (value) => { 538 | field.loading = true 539 | service(value).then((data) => { 540 | field.setState({ 541 | dataSource: data, 542 | loading: false, 543 | }) 544 | }) 545 | } 546 | 547 | const form = createForm() 548 | 549 | const schema = { 550 | type: 'object', 551 | properties: { 552 | selectTable: { 553 | type: 'array', 554 | 'x-decorator': 'FormItem', 555 | 'x-component': 'SelectTable', 556 | 'x-component-props': { 557 | showSearch: true, 558 | filterOption: false, 559 | onSearch: '{{useAsyncDataSource(loadData,$self)}}', 560 | }, 561 | enum: [ 562 | { key: '1', name: 'title-1', description: 'description-1' }, 563 | { key: '2', name: 'title-2', description: 'description-2' }, 564 | ], 565 | properties: { 566 | name: { 567 | title: 'Title', 568 | type: 'string', 569 | 'x-component': 'SelectTable.Column', 570 | 'x-component-props': { 571 | width: '40%', 572 | }, 573 | }, 574 | description: { 575 | title: 'Description', 576 | type: 'string', 577 | 'x-component': 'SelectTable.Column', 578 | 'x-component-props': { 579 | width: '60%', 580 | }, 581 | }, 582 | }, 583 | }, 584 | }, 585 | } 586 | 587 | export default () => ( 588 | <FormProvider form={form}> 589 | <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} /> 590 | <FormButtonGroup> 591 | <Submit onSubmit={console.log}>Submit</Submit> 592 | </FormButtonGroup> 593 | </FormProvider> 594 | ) 595 | ``` 596 | 597 | ## Pure JSX case 598 | 599 | ```tsx 600 | import React from 'react' 601 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' 602 | import { createForm } from '@formily/core' 603 | import { FormProvider, Field } from '@formily/react' 604 | 605 | const form = createForm() 606 | 607 | export default () => ( 608 | <FormProvider form={form}> 609 | <Field 610 | name="SelectTable" 611 | dataSource={[ 612 | { key: '1', name: 'title-1', description: 'description-1' }, 613 | { key: '2', name: 'title-2', description: 'description-2' }, 614 | ]} 615 | decorator={[FormItem]} 616 | component={[ 617 | SelectTable, 618 | { 619 | columns: [ 620 | { dataIndex: 'name', title: 'Title' }, 621 | { dataIndex: 'description', title: 'Description' }, 622 | ], 623 | }, 624 | ]} 625 | /> 626 | <FormButtonGroup> 627 | <Submit onSubmit={console.log}>Submit</Submit> 628 | </FormButtonGroup> 629 | </FormProvider> 630 | ) 631 | ``` 632 | 633 | ## API 634 | 635 | ### SelectTable 636 | 637 | | Property name | Type | Description | Default value | 638 | | ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | 639 | | mode | `'multiple' \| 'single'` | Set mode of SelectTable | `'multiple'` | 640 | | valueType | `'all' \| 'parent' \| 'child' \| 'path'` | value type, Only applies when checkStrictly is set to `false` | `'all'` | 641 | | optionAsValue | boolean | use `option` as value, Only applies when valueType is not set to `'path'` | false | 642 | | showSearch | boolean | show `Search` component | false | 643 | | searchProps | object | `Search` component props | - | 644 | | primaryKey | `string \| (record) => string` | Row's unique key | `'key'` | 645 | | filterOption | `boolean \| (inputValue, option) => boolean` | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | 646 | | filterSort | (optionA, optionB) => number | Sort function for search options sorting, see Array.sort's compareFunction | - | 647 | | onSearch | Callback function that is fired when input changed | (inputValue) => void | - | 648 | 649 | `TableProps` type definition reference antd https://ant.design/components/table/ 650 | 651 | ### rowSelection 652 | 653 | | Property name | Type | Description | Default value | 654 | | ------------- | ------- | -------------------------------------------------------------------------- | ------------- | 655 | | checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true | 656 | 657 | `rowSelectionProps` type definition reference antd https://ant.design/components/table/#rowSelection 658 | 659 | ### SelectTable.Column 660 | 661 | `ColumnProps` type definition reference antd https://ant.design/components/table/ Table.Column 662 | ``` -------------------------------------------------------------------------------- /packages/antd/docs/components/ArrayItems.zh-CN.md: -------------------------------------------------------------------------------- ```markdown 1 | # ArrayItems 2 | 3 | > 自增列表,对于简单的自增编辑场景比较适合,或者对于空间要求高的场景比较适合 4 | > 5 | > 注意:该组件只适用于 Schema 场景 6 | 7 | ## Markup Schema 案例 8 | 9 | ```tsx 10 | import React from 'react' 11 | import { 12 | FormItem, 13 | Input, 14 | Editable, 15 | Select, 16 | DatePicker, 17 | ArrayItems, 18 | FormButtonGroup, 19 | Submit, 20 | Space, 21 | } from '@formily/antd' 22 | import { createForm } from '@formily/core' 23 | import { FormProvider, createSchemaField } from '@formily/react' 24 | 25 | const SchemaField = createSchemaField({ 26 | components: { 27 | FormItem, 28 | DatePicker, 29 | Editable, 30 | Space, 31 | Input, 32 | Select, 33 | ArrayItems, 34 | }, 35 | }) 36 | 37 | const form = createForm() 38 | 39 | export default () => { 40 | return ( 41 | <FormProvider form={form}> 42 | <SchemaField> 43 | <SchemaField.Array 44 | name="string_array" 45 | title="字符串数组" 46 | x-decorator="FormItem" 47 | x-component="ArrayItems" 48 | > 49 | <SchemaField.Void x-component="Space"> 50 | <SchemaField.Void 51 | x-decorator="FormItem" 52 | x-component="ArrayItems.SortHandle" 53 | /> 54 | <SchemaField.String 55 | x-decorator="FormItem" 56 | required 57 | name="input" 58 | x-component="Input" 59 | /> 60 | <SchemaField.Void 61 | x-decorator="FormItem" 62 | x-component="ArrayItems.Remove" 63 | /> 64 | <SchemaField.Void 65 | x-decorator="FormItem" 66 | x-component="ArrayItems.Copy" 67 | /> 68 | </SchemaField.Void> 69 | <SchemaField.Void 70 | x-component="ArrayItems.Addition" 71 | title="添加条目" 72 | /> 73 | </SchemaField.Array> 74 | <SchemaField.Array 75 | name="array" 76 | title="对象数组" 77 | x-decorator="FormItem" 78 | x-component="ArrayItems" 79 | > 80 | <SchemaField.Object> 81 | <SchemaField.Void x-component="Space"> 82 | <SchemaField.Void 83 | x-decorator="FormItem" 84 | x-component="ArrayItems.SortHandle" 85 | /> 86 | <SchemaField.String 87 | x-decorator="FormItem" 88 | required 89 | title="日期" 90 | name="date" 91 | x-component="DatePicker.RangePicker" 92 | x-component-props={{ 93 | style: { 94 | width: 160, 95 | }, 96 | }} 97 | /> 98 | <SchemaField.String 99 | x-decorator="FormItem" 100 | required 101 | title="输入框" 102 | name="input" 103 | x-component="Input" 104 | /> 105 | <SchemaField.String 106 | x-decorator="FormItem" 107 | required 108 | title="选择框" 109 | name="select" 110 | enum={[ 111 | { label: '选项1', value: 1 }, 112 | { label: '选项2', value: 2 }, 113 | ]} 114 | x-component="Select" 115 | x-component-props={{ 116 | style: { 117 | width: 160, 118 | }, 119 | }} 120 | /> 121 | <SchemaField.Void 122 | x-decorator="FormItem" 123 | x-component="ArrayItems.Remove" 124 | /> 125 | <SchemaField.Void 126 | x-decorator="FormItem" 127 | x-component="ArrayItems.Copy" 128 | /> 129 | </SchemaField.Void> 130 | </SchemaField.Object> 131 | <SchemaField.Void 132 | x-component="ArrayItems.Addition" 133 | title="添加条目" 134 | /> 135 | </SchemaField.Array> 136 | <SchemaField.Array 137 | name="array2" 138 | title="对象数组" 139 | x-decorator="FormItem" 140 | x-component="ArrayItems" 141 | x-component-props={{ style: { width: 300 } }} 142 | > 143 | <SchemaField.Object x-decorator="ArrayItems.Item"> 144 | <SchemaField.Void 145 | x-decorator="FormItem" 146 | x-component="ArrayItems.SortHandle" 147 | /> 148 | <SchemaField.String 149 | x-decorator="Editable" 150 | title="输入框" 151 | name="input" 152 | x-component="Input" 153 | x-component-props={{ bordered: false }} 154 | /> 155 | <SchemaField.Object 156 | name="config" 157 | x-component="Editable.Popover" 158 | required 159 | title="配置复杂数据" 160 | x-reactions={(field) => { 161 | field.title = field.value?.input || field.title 162 | }} 163 | > 164 | <SchemaField.String 165 | x-decorator="FormItem" 166 | required 167 | title="日期" 168 | name="date" 169 | x-component="DatePicker.RangePicker" 170 | x-component-props={{ style: { width: '100%' } }} 171 | /> 172 | <SchemaField.String 173 | x-decorator="FormItem" 174 | required 175 | title="输入框" 176 | name="input" 177 | x-component="Input" 178 | /> 179 | </SchemaField.Object> 180 | <SchemaField.Void 181 | x-decorator="FormItem" 182 | x-component="ArrayItems.Remove" 183 | /> 184 | </SchemaField.Object> 185 | <SchemaField.Void 186 | x-component="ArrayItems.Addition" 187 | title="添加条目" 188 | /> 189 | </SchemaField.Array> 190 | </SchemaField> 191 | <FormButtonGroup> 192 | <Submit onSubmit={console.log}>提交</Submit> 193 | </FormButtonGroup> 194 | </FormProvider> 195 | ) 196 | } 197 | ``` 198 | 199 | ## JSON Schema 案例 200 | 201 | ```tsx 202 | import React from 'react' 203 | import { 204 | FormItem, 205 | Editable, 206 | Input, 207 | Select, 208 | Radio, 209 | DatePicker, 210 | ArrayItems, 211 | FormButtonGroup, 212 | Submit, 213 | Space, 214 | } from '@formily/antd' 215 | import { createForm } from '@formily/core' 216 | import { FormProvider, createSchemaField } from '@formily/react' 217 | 218 | const SchemaField = createSchemaField({ 219 | components: { 220 | FormItem, 221 | Editable, 222 | DatePicker, 223 | Space, 224 | Radio, 225 | Input, 226 | Select, 227 | ArrayItems, 228 | }, 229 | }) 230 | 231 | const form = createForm() 232 | 233 | const schema = { 234 | type: 'object', 235 | properties: { 236 | string_array: { 237 | type: 'array', 238 | 'x-component': 'ArrayItems', 239 | 'x-decorator': 'FormItem', 240 | title: '字符串数组', 241 | items: { 242 | type: 'void', 243 | 'x-component': 'Space', 244 | properties: { 245 | sort: { 246 | type: 'void', 247 | 'x-decorator': 'FormItem', 248 | 'x-component': 'ArrayItems.SortHandle', 249 | }, 250 | input: { 251 | type: 'string', 252 | 'x-decorator': 'FormItem', 253 | 'x-component': 'Input', 254 | }, 255 | remove: { 256 | type: 'void', 257 | 'x-decorator': 'FormItem', 258 | 'x-component': 'ArrayItems.Remove', 259 | }, 260 | }, 261 | }, 262 | properties: { 263 | add: { 264 | type: 'void', 265 | title: '添加条目', 266 | 'x-component': 'ArrayItems.Addition', 267 | }, 268 | }, 269 | }, 270 | array: { 271 | type: 'array', 272 | 'x-component': 'ArrayItems', 273 | 'x-decorator': 'FormItem', 274 | title: '对象数组', 275 | items: { 276 | type: 'object', 277 | properties: { 278 | space: { 279 | type: 'void', 280 | 'x-component': 'Space', 281 | properties: { 282 | sort: { 283 | type: 'void', 284 | 'x-decorator': 'FormItem', 285 | 'x-component': 'ArrayItems.SortHandle', 286 | }, 287 | date: { 288 | type: 'string', 289 | title: '日期', 290 | 'x-decorator': 'FormItem', 291 | 'x-component': 'DatePicker.RangePicker', 292 | 'x-component-props': { 293 | style: { 294 | width: 160, 295 | }, 296 | }, 297 | }, 298 | input: { 299 | type: 'string', 300 | title: '输入框', 301 | 'x-decorator': 'FormItem', 302 | 'x-component': 'Input', 303 | }, 304 | select: { 305 | type: 'string', 306 | title: '下拉框', 307 | enum: [ 308 | { label: '选项1', value: 1 }, 309 | { label: '选项2', value: 2 }, 310 | ], 311 | 'x-decorator': 'FormItem', 312 | 'x-component': 'Select', 313 | 'x-component-props': { 314 | style: { 315 | width: 160, 316 | }, 317 | }, 318 | }, 319 | remove: { 320 | type: 'void', 321 | 'x-decorator': 'FormItem', 322 | 'x-component': 'ArrayItems.Remove', 323 | }, 324 | }, 325 | }, 326 | }, 327 | }, 328 | properties: { 329 | add: { 330 | type: 'void', 331 | title: '添加条目', 332 | 'x-component': 'ArrayItems.Addition', 333 | }, 334 | }, 335 | }, 336 | array2: { 337 | type: 'array', 338 | 'x-component': 'ArrayItems', 339 | 'x-decorator': 'FormItem', 340 | 'x-component-props': { style: { width: 300 } }, 341 | title: '对象数组', 342 | items: { 343 | type: 'object', 344 | 'x-decorator': 'ArrayItems.Item', 345 | properties: { 346 | sort: { 347 | type: 'void', 348 | 'x-decorator': 'FormItem', 349 | 'x-component': 'ArrayItems.SortHandle', 350 | }, 351 | 352 | input: { 353 | type: 'string', 354 | title: '输入框', 355 | 'x-decorator': 'Editable', 356 | 'x-component': 'Input', 357 | 'x-component-props': { 358 | bordered: false, 359 | }, 360 | }, 361 | config: { 362 | type: 'object', 363 | title: '配置复杂数据', 364 | 'x-component': 'Editable.Popover', 365 | 'x-reactions': 366 | '{{(field)=>field.title = field.value && field.value.input || field.title}}', 367 | properties: { 368 | date: { 369 | type: 'string', 370 | title: '日期', 371 | 'x-decorator': 'FormItem', 372 | 'x-component': 'DatePicker.RangePicker', 373 | 'x-component-props': { 374 | style: { 375 | width: 160, 376 | }, 377 | }, 378 | }, 379 | input: { 380 | type: 'string', 381 | title: '输入框', 382 | 'x-decorator': 'FormItem', 383 | 'x-component': 'Input', 384 | }, 385 | select: { 386 | type: 'string', 387 | title: '下拉框', 388 | enum: [ 389 | { label: '选项1', value: 1 }, 390 | { label: '选项2', value: 2 }, 391 | ], 392 | 'x-decorator': 'FormItem', 393 | 'x-component': 'Select', 394 | 'x-component-props': { 395 | style: { 396 | width: 160, 397 | }, 398 | }, 399 | }, 400 | }, 401 | }, 402 | remove: { 403 | type: 'void', 404 | 'x-decorator': 'FormItem', 405 | 'x-component': 'ArrayItems.Remove', 406 | }, 407 | }, 408 | }, 409 | properties: { 410 | add: { 411 | type: 'void', 412 | title: '添加条目', 413 | 'x-component': 'ArrayItems.Addition', 414 | }, 415 | }, 416 | }, 417 | }, 418 | } 419 | 420 | export default () => { 421 | return ( 422 | <FormProvider form={form}> 423 | <SchemaField schema={schema} /> 424 | <FormButtonGroup> 425 | <Submit onSubmit={console.log}>提交</Submit> 426 | </FormButtonGroup> 427 | </FormProvider> 428 | ) 429 | } 430 | ``` 431 | 432 | ## Effects 联动案例 433 | 434 | ```tsx 435 | import React from 'react' 436 | import { 437 | FormItem, 438 | Input, 439 | ArrayItems, 440 | Editable, 441 | FormButtonGroup, 442 | Submit, 443 | Space, 444 | } from '@formily/antd' 445 | import { createForm, onFieldChange, onFieldReact } from '@formily/core' 446 | import { FormProvider, createSchemaField } from '@formily/react' 447 | 448 | const SchemaField = createSchemaField({ 449 | components: { 450 | Space, 451 | Editable, 452 | FormItem, 453 | Input, 454 | ArrayItems, 455 | }, 456 | }) 457 | 458 | const form = createForm({ 459 | effects: () => { 460 | //主动联动模式 461 | onFieldChange('array.*.aa', ['value'], (field, form) => { 462 | form.setFieldState(field.query('.bb'), (state) => { 463 | state.visible = field.value != '123' 464 | }) 465 | }) 466 | //被动联动模式 467 | onFieldReact('array.*.dd', (field) => { 468 | field.visible = field.query('.cc').get('value') != '123' 469 | }) 470 | }, 471 | }) 472 | 473 | export default () => { 474 | return ( 475 | <FormProvider form={form}> 476 | <SchemaField> 477 | <SchemaField.Array 478 | name="array" 479 | title="对象数组" 480 | maxItems={3} 481 | x-decorator="FormItem" 482 | x-component="ArrayItems" 483 | x-component-props={{ 484 | style: { 485 | width: 300, 486 | }, 487 | }} 488 | > 489 | <SchemaField.Object x-decorator="ArrayItems.Item"> 490 | <SchemaField.Void x-component="Space"> 491 | <SchemaField.Void 492 | x-decorator="FormItem" 493 | x-component="ArrayItems.SortHandle" 494 | /> 495 | <SchemaField.Void 496 | x-decorator="FormItem" 497 | x-component="ArrayItems.Index" 498 | /> 499 | </SchemaField.Void> 500 | <SchemaField.Void x-component="Editable.Popover" title="配置数据"> 501 | <SchemaField.String 502 | name="aa" 503 | x-decorator="FormItem" 504 | title="AA" 505 | required 506 | description="AA输入123时隐藏BB" 507 | x-component="Input" 508 | /> 509 | <SchemaField.String 510 | name="bb" 511 | x-decorator="FormItem" 512 | title="BB" 513 | required 514 | x-component="Input" 515 | /> 516 | <SchemaField.String 517 | name="cc" 518 | x-decorator="FormItem" 519 | title="CC" 520 | required 521 | description="CC输入123时隐藏DD" 522 | x-component="Input" 523 | /> 524 | <SchemaField.String 525 | name="dd" 526 | x-decorator="FormItem" 527 | title="DD" 528 | required 529 | x-component="Input" 530 | /> 531 | </SchemaField.Void> 532 | <SchemaField.Void x-component="Space"> 533 | <SchemaField.Void 534 | x-decorator="FormItem" 535 | x-component="ArrayItems.Remove" 536 | /> 537 | <SchemaField.Void 538 | x-decorator="FormItem" 539 | x-component="ArrayItems.MoveUp" 540 | /> 541 | <SchemaField.Void 542 | x-decorator="FormItem" 543 | x-component="ArrayItems.MoveDown" 544 | /> 545 | </SchemaField.Void> 546 | </SchemaField.Object> 547 | <SchemaField.Void 548 | x-component="ArrayItems.Addition" 549 | title="添加条目" 550 | /> 551 | </SchemaField.Array> 552 | </SchemaField> 553 | <FormButtonGroup> 554 | <Submit onSubmit={console.log}>提交</Submit> 555 | </FormButtonGroup> 556 | </FormProvider> 557 | ) 558 | } 559 | ``` 560 | 561 | ## JSON Schema 联动案例 562 | 563 | ```tsx 564 | import React from 'react' 565 | import { 566 | FormItem, 567 | Input, 568 | ArrayItems, 569 | Editable, 570 | FormButtonGroup, 571 | Submit, 572 | Space, 573 | } from '@formily/antd' 574 | import { createForm } from '@formily/core' 575 | import { FormProvider, createSchemaField } from '@formily/react' 576 | 577 | const SchemaField = createSchemaField({ 578 | components: { 579 | Space, 580 | Editable, 581 | FormItem, 582 | Input, 583 | ArrayItems, 584 | }, 585 | }) 586 | 587 | const form = createForm() 588 | 589 | const schema = { 590 | type: 'object', 591 | properties: { 592 | array: { 593 | type: 'array', 594 | 'x-component': 'ArrayItems', 595 | 'x-decorator': 'FormItem', 596 | maxItems: 3, 597 | title: '对象数组', 598 | 'x-component-props': { style: { width: 300 } }, 599 | items: { 600 | type: 'object', 601 | 'x-decorator': 'ArrayItems.Item', 602 | properties: { 603 | left: { 604 | type: 'void', 605 | 'x-component': 'Space', 606 | properties: { 607 | sort: { 608 | type: 'void', 609 | 'x-decorator': 'FormItem', 610 | 'x-component': 'ArrayItems.SortHandle', 611 | }, 612 | index: { 613 | type: 'void', 614 | 'x-decorator': 'FormItem', 615 | 'x-component': 'ArrayItems.Index', 616 | }, 617 | }, 618 | }, 619 | edit: { 620 | type: 'void', 621 | 'x-component': 'Editable.Popover', 622 | title: '配置数据', 623 | properties: { 624 | aa: { 625 | type: 'string', 626 | 'x-decorator': 'FormItem', 627 | title: 'AA', 628 | required: true, 629 | 'x-component': 'Input', 630 | description: '输入123', 631 | }, 632 | bb: { 633 | type: 'string', 634 | title: 'BB', 635 | required: true, 636 | 'x-decorator': 'FormItem', 637 | 'x-component': 'Input', 638 | 'x-reactions': [ 639 | { 640 | dependencies: ['.aa'], 641 | when: "{{$deps[0] != '123'}}", 642 | fulfill: { 643 | schema: { 644 | title: 'BB', 645 | 'x-disabled': true, 646 | }, 647 | }, 648 | otherwise: { 649 | schema: { 650 | title: 'Changed', 651 | 'x-disabled': false, 652 | }, 653 | }, 654 | }, 655 | ], 656 | }, 657 | }, 658 | }, 659 | right: { 660 | type: 'void', 661 | 'x-component': 'Space', 662 | properties: { 663 | remove: { 664 | type: 'void', 665 | 'x-component': 'ArrayItems.Remove', 666 | }, 667 | moveUp: { 668 | type: 'void', 669 | 'x-component': 'ArrayItems.MoveUp', 670 | }, 671 | moveDown: { 672 | type: 'void', 673 | 'x-component': 'ArrayItems.MoveDown', 674 | }, 675 | }, 676 | }, 677 | }, 678 | }, 679 | properties: { 680 | addition: { 681 | type: 'void', 682 | title: '添加条目', 683 | 'x-component': 'ArrayItems.Addition', 684 | }, 685 | }, 686 | }, 687 | }, 688 | } 689 | 690 | export default () => { 691 | return ( 692 | <FormProvider form={form}> 693 | <SchemaField schema={schema} /> 694 | <FormButtonGroup> 695 | <Submit onSubmit={console.log}>提交</Submit> 696 | </FormButtonGroup> 697 | </FormProvider> 698 | ) 699 | } 700 | ``` 701 | 702 | ## API 703 | 704 | ### ArrayItems 705 | 706 | 扩展属性 707 | 708 | | 属性名 | 类型 | 描述 | 默认值 | 709 | | ---------- | ------------------------- | ------------ | ------ | 710 | | onAdd | `(index: number) => void` | 增加方法 | | 711 | | onRemove | `(index: number) => void` | 删除方法 | | 712 | | onCopy | `(index: number) => void` | 复制方法 | | 713 | | onMoveUp | `(index: number) => void` | 向上移动方法 | | 714 | | onMoveDown | `(index: number) => void` | 向下移动方法 | | 715 | 716 | 其余继承 HTMLDivElement Props 717 | 718 | ### ArrayItems.Item 719 | 720 | > 列表区块 721 | 722 | 继承 HTMLDivElement Props 723 | 724 | 扩展属性 725 | 726 | | 属性名 | 类型 | 描述 | 默认值 | 727 | | ------ | -------------------- | -------------- | ------ | 728 | | type | `'card' \| 'divide'` | 卡片或者分割线 | | 729 | 730 | ### ArrayItems.SortHandle 731 | 732 | > 拖拽手柄 733 | 734 | 参考 https://ant.design/components/icon-cn/ 735 | 736 | ### ArrayItems.Addition 737 | 738 | > 添加按钮 739 | 740 | 扩展属性 741 | 742 | | 属性名 | 类型 | 描述 | 默认值 | 743 | | ------------ | --------------------- | -------- | -------- | 744 | | title | ReactText | 文案 | | 745 | | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | 746 | | defaultValue | `any` | 默认值 | | 747 | 748 | 其余参考 https://ant.design/components/button-cn/ 749 | 750 | 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 751 | 752 | 注意:使用`onClick={e => e.preventDefault()}`可禁用默认行为。 753 | 754 | ### ArrayItems.Copy 755 | 756 | > 复制按钮 757 | 758 | 扩展属性 759 | 760 | | 属性名 | 类型 | 描述 | 默认值 | 761 | | ------ | --------------------- | -------- | -------- | 762 | | title | ReactText | 文案 | | 763 | | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | 764 | 765 | 其余参考 https://ant.design/components/button-cn/ 766 | 767 | 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 768 | 769 | 注意:使用`onClick={e => e.preventDefault()}`可禁用默认行为。 770 | 771 | ### ArrayItems.Remove 772 | 773 | > 删除按钮 774 | 775 | | 属性名 | 类型 | 描述 | 默认值 | 776 | | ------ | --------- | ---- | ------ | 777 | | title | ReactText | 文案 | | 778 | 779 | 其余参考 https://ant.design/components/icon-cn/ 780 | 781 | 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 782 | 783 | 注意:使用`onClick={e => e.preventDefault()}`可禁用默认行为。 784 | 785 | ### ArrayItems.MoveDown 786 | 787 | > 下移按钮 788 | 789 | | 属性名 | 类型 | 描述 | 默认值 | 790 | | ------ | --------- | ---- | ------ | 791 | | title | ReactText | 文案 | | 792 | 793 | 其余参考 https://ant.design/components/icon-cn/ 794 | 795 | 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 796 | 797 | 注意:使用`onClick={e => e.preventDefault()}`可禁用默认行为。 798 | 799 | ### ArrayItems.MoveUp 800 | 801 | > 上移按钮 802 | 803 | | 属性名 | 类型 | 描述 | 默认值 | 804 | | ------ | --------- | ---- | ------ | 805 | | title | ReactText | 文案 | | 806 | 807 | 其余参考 https://ant.design/components/icon-cn/ 808 | 809 | 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 810 | 811 | 注意:使用`onClick={e => e.preventDefault()}`可禁用默认行为。 812 | 813 | ### ArrayItems.Index 814 | 815 | > 索引渲染器 816 | 817 | 无属性 818 | 819 | ### ArrayItems.useIndex 820 | 821 | > 读取当前渲染行索引的 React Hook 822 | 823 | ### ArrayItems.useRecord 824 | 825 | > 读取当前渲染记录的 React Hook 826 | ``` -------------------------------------------------------------------------------- /packages/next/docs/components/SelectTable.md: -------------------------------------------------------------------------------- ```markdown 1 | # SelectTable 2 | 3 | > Optional table components 4 | 5 | ## Markup Schema single case 6 | 7 | ```tsx 8 | import React from 'react' 9 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 10 | import { createForm } from '@formily/core' 11 | import { FormProvider, createSchemaField } from '@formily/react' 12 | 13 | const SchemaField = createSchemaField({ 14 | components: { 15 | FormItem, 16 | SelectTable, 17 | }, 18 | }) 19 | 20 | const form = createForm() 21 | 22 | export default () => { 23 | return ( 24 | <FormProvider form={form}> 25 | <SchemaField> 26 | <SchemaField.Object 27 | type="string" 28 | name="selectTable" 29 | x-decorator="FormItem" 30 | x-component="SelectTable" 31 | x-component-props={{ 32 | hasBorder: false, 33 | mode: 'single', 34 | }} 35 | enum={[ 36 | { key: '1', name: 'title-1', description: 'description-1' }, 37 | { key: '2', name: 'Title-2', description: 'description-2' }, 38 | ]} 39 | > 40 | <SchemaField.Void 41 | name="name" 42 | title="Title" 43 | x-component="SelectTable.Column" 44 | /> 45 | <SchemaField.Void 46 | name="description" 47 | title="Description" 48 | x-component="SelectTable.Column" 49 | /> 50 | </SchemaField.Object> 51 | </SchemaField> 52 | <FormButtonGroup.FormItem> 53 | <Submit onSubmit={console.log}>Submit</Submit> 54 | </FormButtonGroup.FormItem> 55 | </FormProvider> 56 | ) 57 | } 58 | ``` 59 | 60 | ## Markup Schema filter case 61 | 62 | ```tsx 63 | import React from 'react' 64 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 65 | import { createForm } from '@formily/core' 66 | import { FormProvider, createSchemaField } from '@formily/react' 67 | 68 | const SchemaField = createSchemaField({ 69 | components: { 70 | FormItem, 71 | SelectTable, 72 | }, 73 | }) 74 | 75 | const form = createForm() 76 | 77 | export default () => { 78 | return ( 79 | <FormProvider form={form}> 80 | <SchemaField> 81 | <SchemaField.Array 82 | type="array" 83 | name="selectTable" 84 | x-decorator="FormItem" 85 | x-component="SelectTable" 86 | x-component-props={{ 87 | hasBorder: false, 88 | showSearch: true, 89 | optionAsValue: true, 90 | }} 91 | enum={[ 92 | { key: '1', name: 'title-1', description: 'description-1' }, 93 | { key: '2', name: 'Title-2', description: 'description-2' }, 94 | ]} 95 | > 96 | <SchemaField.Object> 97 | <SchemaField.Void 98 | name="name" 99 | title="Title" 100 | x-component="SelectTable.Column" 101 | /> 102 | <SchemaField.Void 103 | name="description" 104 | title="Description" 105 | x-component="SelectTable.Column" 106 | /> 107 | </SchemaField.Object> 108 | </SchemaField.Array> 109 | </SchemaField> 110 | <FormButtonGroup.FormItem> 111 | <Submit onSubmit={console.log}>Submit</Submit> 112 | </FormButtonGroup.FormItem> 113 | </FormProvider> 114 | ) 115 | } 116 | ``` 117 | 118 | ## Markup Schema async data source case 119 | 120 | ```tsx 121 | import React from 'react' 122 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 123 | import { createForm } from '@formily/core' 124 | import { FormProvider, createSchemaField } from '@formily/react' 125 | 126 | const SchemaField = createSchemaField({ 127 | components: { 128 | FormItem, 129 | SelectTable, 130 | }, 131 | }) 132 | 133 | const form = createForm() 134 | 135 | export default () => { 136 | const onSearch = (value) => { 137 | const field = form.query('selectTable').take() 138 | field.loading = true 139 | setTimeout(() => { 140 | field.setState({ 141 | dataSource: [ 142 | { 143 | key: '3', 144 | name: 'AAA' + value, 145 | description: 'aaa', 146 | }, 147 | { 148 | key: '4', 149 | name: 'BBB' + value, 150 | description: 'bbb', 151 | }, 152 | ], 153 | loading: false, 154 | }) 155 | }, 1500) 156 | } 157 | 158 | return ( 159 | <FormProvider form={form}> 160 | <SchemaField> 161 | <SchemaField.Object 162 | type="object" 163 | name="selectTable" 164 | x-decorator="FormItem" 165 | x-component="SelectTable" 166 | x-component-props={{ 167 | hasBorder: false, 168 | showSearch: true, 169 | filterOption: false, 170 | onSearch, 171 | }} 172 | enum={[ 173 | { key: '1', name: 'title-1', description: 'description-1' }, 174 | { key: '2', name: 'title-2', description: 'description-2' }, 175 | ]} 176 | > 177 | <SchemaField.Void 178 | name="name" 179 | title="Title" 180 | x-component="SelectTable.Column" 181 | /> 182 | <SchemaField.Void 183 | name="description" 184 | title="Description" 185 | x-component="SelectTable.Column" 186 | /> 187 | </SchemaField.Object> 188 | </SchemaField> 189 | <FormButtonGroup.FormItem> 190 | <Submit onSubmit={console.log}>Submit</Submit> 191 | </FormButtonGroup.FormItem> 192 | </FormProvider> 193 | ) 194 | } 195 | ``` 196 | 197 | ## Markup Schema read-pretty case 198 | 199 | ```tsx 200 | import React from 'react' 201 | import { 202 | Form, 203 | FormItem, 204 | FormButtonGroup, 205 | Submit, 206 | SelectTable, 207 | } from '@formily/next' 208 | import { createForm } from '@formily/core' 209 | import { createSchemaField } from '@formily/react' 210 | 211 | const SchemaField = createSchemaField({ 212 | components: { 213 | FormItem, 214 | SelectTable, 215 | }, 216 | }) 217 | 218 | const form = createForm() 219 | 220 | export default () => { 221 | return ( 222 | <Form form={form} layout="vertical"> 223 | <SchemaField> 224 | <SchemaField.Object 225 | title="single" 226 | type="string" 227 | name="selectTable1" 228 | x-decorator="FormItem" 229 | x-component="SelectTable" 230 | x-component-props={{ 231 | hasBorder: false, 232 | mode: 'single', 233 | }} 234 | default="1" 235 | enum={[ 236 | { key: '1', name: 'title-1', description: 'description-1' }, 237 | { key: '2', name: 'Title-2', description: 'description-2' }, 238 | ]} 239 | x-read-pretty={true} 240 | > 241 | <SchemaField.Void 242 | name="name" 243 | title="Title" 244 | x-component="SelectTable.Column" 245 | /> 246 | <SchemaField.Void 247 | name="description" 248 | title="Description" 249 | x-component="SelectTable.Column" 250 | /> 251 | </SchemaField.Object> 252 | <SchemaField.Object 253 | title="single + optionAsValue" 254 | type="string" 255 | name="selectTable2" 256 | x-decorator="FormItem" 257 | x-component="SelectTable" 258 | x-component-props={{ 259 | hasBorder: false, 260 | mode: 'single', 261 | optionAsValue: true, 262 | }} 263 | default={{ key: '1', name: 'Title1', description: 'Description1' }} 264 | enum={[ 265 | { key: '1', name: 'title-1', description: 'description-1' }, 266 | { key: '2', name: 'Title-2', description: 'description-2' }, 267 | ]} 268 | x-read-pretty={true} 269 | > 270 | <SchemaField.Void 271 | name="name" 272 | title="Title" 273 | x-component="SelectTable.Column" 274 | /> 275 | <SchemaField.Void 276 | name="description" 277 | title="Description" 278 | x-component="SelectTable.Column" 279 | /> 280 | </SchemaField.Object> 281 | <SchemaField.Array 282 | title="multiple" 283 | type="array" 284 | name="selectTable3" 285 | x-decorator="FormItem" 286 | x-component="SelectTable" 287 | x-component-props={{ 288 | hasBorder: false, 289 | }} 290 | default={['1', '3']} 291 | enum={[ 292 | { key: '1', name: 'title-1', description: 'description-1' }, 293 | { key: '2', name: 'Title-2', description: 'description-2' }, 294 | { key: '3', name: 'title-3', description: 'description-3' }, 295 | ]} 296 | x-read-pretty={true} 297 | > 298 | <SchemaField.Object> 299 | <SchemaField.Void 300 | name="name" 301 | title="Title" 302 | x-component="SelectTable.Column" 303 | /> 304 | <SchemaField.Void 305 | name="description" 306 | title="Description" 307 | x-component="SelectTable.Column" 308 | /> 309 | </SchemaField.Object> 310 | </SchemaField.Array> 311 | <SchemaField.Array 312 | title="multiple + optionAsValue" 313 | type="array" 314 | name="selectTable4" 315 | x-decorator="FormItem" 316 | x-component="SelectTable" 317 | x-component-props={{ 318 | hasBorder: false, 319 | optionAsValue: true, 320 | }} 321 | default={[ 322 | { key: '1', name: 'title-1', description: 'description-1' }, 323 | { key: '3', name: 'title-3', description: 'description-3' }, 324 | ]} 325 | enum={[ 326 | { key: '1', name: 'title-1', description: 'description-1' }, 327 | { key: '2', name: 'Title-2', description: 'description-2' }, 328 | { key: '3', name: 'title-3', description: 'description-3' }, 329 | ]} 330 | x-read-pretty={true} 331 | > 332 | <SchemaField.Object> 333 | <SchemaField.Void 334 | name="name" 335 | title="Title" 336 | x-component="SelectTable.Column" 337 | /> 338 | <SchemaField.Void 339 | name="description" 340 | title="Description" 341 | x-component="SelectTable.Column" 342 | /> 343 | </SchemaField.Object> 344 | </SchemaField.Array> 345 | </SchemaField> 346 | <FormButtonGroup.FormItem> 347 | <Submit onSubmit={console.log}>Submit</Submit> 348 | </FormButtonGroup.FormItem> 349 | </Form> 350 | ) 351 | } 352 | ``` 353 | 354 | ## JSON Schema multiple case 355 | 356 | ```tsx 357 | import React from 'react' 358 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 359 | import { createForm } from '@formily/core' 360 | import { FormProvider, createSchemaField } from '@formily/react' 361 | 362 | const SchemaField = createSchemaField({ 363 | components: { 364 | SelectTable, 365 | FormItem, 366 | }, 367 | }) 368 | 369 | const form = createForm() 370 | 371 | const schema = { 372 | type: 'object', 373 | properties: { 374 | selectTable: { 375 | type: 'array', 376 | 'x-decorator': 'FormItem', 377 | 'x-component': 'SelectTable', 378 | 'x-component-props': { 379 | hasBorder: false, 380 | mode: 'multiple', 381 | }, 382 | enum: [ 383 | { key: '1', name: 'title-1', description: 'description-1' }, 384 | { key: '2', name: 'Title-2', description: 'description-2' }, 385 | ], 386 | properties: { 387 | name: { 388 | title: 'Title', 389 | type: 'string', 390 | 'x-component': 'SelectTable.Column', 391 | 'x-component-props': { 392 | width: '40%', 393 | }, 394 | }, 395 | description: { 396 | title: 'Description', 397 | type: 'string', 398 | 'x-component': 'SelectTable.Column', 399 | 'x-component-props': { 400 | width: '60%', 401 | }, 402 | }, 403 | }, 404 | }, 405 | }, 406 | } 407 | 408 | export default () => ( 409 | <FormProvider form={form}> 410 | <SchemaField schema={schema} /> 411 | <FormButtonGroup> 412 | <Submit onSubmit={console.log}>Submit</Submit> 413 | </FormButtonGroup> 414 | </FormProvider> 415 | ) 416 | ``` 417 | 418 | ## JSON Schema custom filter case 419 | 420 | ```tsx 421 | import React from 'react' 422 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 423 | import { createForm } from '@formily/core' 424 | import { FormProvider, createSchemaField } from '@formily/react' 425 | 426 | const SchemaField = createSchemaField({ 427 | components: { 428 | SelectTable, 429 | FormItem, 430 | }, 431 | }) 432 | 433 | const form = createForm() 434 | 435 | const schema = { 436 | type: 'object', 437 | properties: { 438 | selectTable: { 439 | type: 'array', 440 | 'x-decorator': 'FormItem', 441 | 'x-component': 'SelectTable', 442 | 'x-component-props': { 443 | hasBorder: false, 444 | showSearch: true, 445 | primaryKey: 'key', 446 | isTree: true, 447 | filterOption: (input, option) => 448 | option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0, 449 | filterSort: (optionA, optionB) => 450 | optionA.description 451 | .toLowerCase() 452 | .localeCompare(optionB.description.toLowerCase()), 453 | optionAsValue: true, 454 | rowSelection: { 455 | checkStrictly: false, 456 | }, 457 | }, 458 | enum: [ 459 | { key: '1', name: 'title-1', description: 'A-description' }, 460 | { 461 | key: '2', 462 | name: 'title-2', 463 | description: 'X-description', 464 | children: [ 465 | { 466 | key: '2-1', 467 | name: 'title2-1', 468 | description: 'Y-description', 469 | children: [ 470 | { 471 | key: '2-1-1', 472 | name: 'title-2-1-1', 473 | description: 'Z-description', 474 | }, 475 | ], 476 | }, 477 | { 478 | key: '2-2', 479 | name: 'title2-2', 480 | description: 'YY-description', 481 | }, 482 | ], 483 | }, 484 | { key: '3', name: 'title-3', description: 'C-description' }, 485 | ], 486 | properties: { 487 | name: { 488 | title: 'Title', 489 | type: 'string', 490 | 'x-component': 'SelectTable.Column', 491 | 'x-component-props': { 492 | width: '40%', 493 | }, 494 | }, 495 | description: { 496 | title: 'Description', 497 | type: 'string', 498 | 'x-component': 'SelectTable.Column', 499 | 'x-component-props': { 500 | width: '60%', 501 | }, 502 | }, 503 | }, 504 | }, 505 | }, 506 | } 507 | 508 | export default () => ( 509 | <FormProvider form={form}> 510 | <SchemaField schema={schema} /> 511 | <FormButtonGroup> 512 | <Submit onSubmit={console.log}>Submit</Submit> 513 | </FormButtonGroup> 514 | </FormProvider> 515 | ) 516 | ``` 517 | 518 | ## JSON Schema async data source case 519 | 520 | ```tsx 521 | import React from 'react' 522 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 523 | import { createForm } from '@formily/core' 524 | import { FormProvider, createSchemaField } from '@formily/react' 525 | 526 | const SchemaField = createSchemaField({ 527 | components: { 528 | SelectTable, 529 | FormItem, 530 | }, 531 | }) 532 | 533 | const loadData = async (value) => { 534 | return new Promise((resolve) => { 535 | setTimeout(() => { 536 | resolve([ 537 | { key: '3', name: 'AAA' + value, description: 'aaa' }, 538 | { key: '4', name: 'BBB' + value, description: 'bbb' }, 539 | ]) 540 | }, 1500) 541 | }) 542 | } 543 | 544 | const useAsyncDataSource = (service, field) => (value) => { 545 | field.loading = true 546 | service(value).then((data) => { 547 | field.setState({ 548 | dataSource: data, 549 | loading: false, 550 | }) 551 | }) 552 | } 553 | 554 | const form = createForm() 555 | 556 | const schema = { 557 | type: 'object', 558 | properties: { 559 | selectTable: { 560 | type: 'array', 561 | 'x-decorator': 'FormItem', 562 | 'x-component': 'SelectTable', 563 | 'x-component-props': { 564 | hasBorder: false, 565 | showSearch: true, 566 | filterOption: false, 567 | onSearch: '{{useAsyncDataSource(loadData,$self)}}', 568 | }, 569 | enum: [ 570 | { key: '1', name: 'title-1', description: 'description-1' }, 571 | { key: '2', name: 'title-2', description: 'description-2' }, 572 | ], 573 | properties: { 574 | name: { 575 | title: 'Title', 576 | type: 'string', 577 | 'x-component': 'SelectTable.Column', 578 | 'x-component-props': { 579 | width: '40%', 580 | }, 581 | }, 582 | description: { 583 | title: 'Description', 584 | type: 'string', 585 | 'x-component': 'SelectTable.Column', 586 | 'x-component-props': { 587 | width: '60%', 588 | }, 589 | }, 590 | }, 591 | }, 592 | }, 593 | } 594 | 595 | export default () => ( 596 | <FormProvider form={form}> 597 | <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} /> 598 | <FormButtonGroup> 599 | <Submit onSubmit={console.log}>Submit</Submit> 600 | </FormButtonGroup> 601 | </FormProvider> 602 | ) 603 | ``` 604 | 605 | ## Pure JSX case 606 | 607 | ```tsx 608 | import React from 'react' 609 | import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next' 610 | import { createForm } from '@formily/core' 611 | import { FormProvider, Field } from '@formily/react' 612 | 613 | const form = createForm() 614 | 615 | export default () => ( 616 | <FormProvider form={form}> 617 | <Field 618 | name="SelectTable" 619 | dataSource={[ 620 | { key: '1', name: 'title-1', description: 'description-1' }, 621 | { key: '2', name: 'title-2', description: 'description-2' }, 622 | ]} 623 | decorator={[FormItem]} 624 | component={[ 625 | SelectTable, 626 | { 627 | hasBorder: false, 628 | columns: [ 629 | { dataIndex: 'name', title: 'Title' }, 630 | { dataIndex: 'description', title: 'Description' }, 631 | ], 632 | }, 633 | ]} 634 | /> 635 | <FormButtonGroup> 636 | <Submit onSubmit={console.log}>Submit</Submit> 637 | </FormButtonGroup> 638 | </FormProvider> 639 | ) 640 | ``` 641 | 642 | ## API 643 | 644 | ### SelectTable 645 | 646 | | Property name | Type | Description | Default value | 647 | | ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | 648 | | mode | `'multiple' \| 'single'` | Set mode of SelectTable | `'multiple'` | 649 | | valueType | `'all' \| 'parent' \| 'child' \| 'path'` | value type, Only applies when checkStrictly is set to `false` | `'all'` | 650 | | optionAsValue | boolean | use `option` as value, Only applies when valueType is not set to `'path'` | false | 651 | | showSearch | boolean | show `Search` component | false | 652 | | searchProps | object | `Search` component props | - | 653 | | primaryKey | `string \| (record) => string` | Row's unique key | `'key'` | 654 | | filterOption | `boolean \| (inputValue, option) => boolean` | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | 655 | | filterSort | (optionA, optionB) => number | Sort function for search options sorting, see Array.sort's compareFunction | - | 656 | | onSearch | Callback function that is fired when input changed | (inputValue) => void | - | 657 | 658 | `TableProps` type definition reference fusion https://fusion.design/pc/component/basic/table 659 | 660 | ### rowSelection 661 | 662 | | Property name | Type | Description | Default value | 663 | | ------------- | ------- | -------------------------------------------------------------------------- | ------------- | 664 | | checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true | 665 | 666 | `rowSelectionProps` type definition reference fusion https://fusion.design/pc/component/basic/table rowSelection 667 | 668 | ### SelectTable.Column 669 | 670 | `ColumnProps` type definition reference fusion https://fusion.design/pc/component/basic/table Table.Column 671 | ``` -------------------------------------------------------------------------------- /packages/next/docs/components/ArrayTable.md: -------------------------------------------------------------------------------- ```markdown 1 | # ArrayTable 2 | 3 | > Self-increasing table, it is more suitable to use this component for scenes with a large amount of data. Although the amount of data is large to a certain extent, it will be a little bit stuck, but it will not affect the basic operation 4 | > 5 | > Note: This component is only applicable to Schema scenarios and can only be an array of objects 6 | 7 | ## Markup Schema example 8 | 9 | ```tsx 10 | import React from 'react' 11 | import { 12 | FormItem, 13 | Input, 14 | ArrayTable, 15 | Editable, 16 | FormButtonGroup, 17 | Submit, 18 | } from '@formily/next' 19 | import { createForm } from '@formily/core' 20 | import { FormProvider, createSchemaField } from '@formily/react' 21 | import { Button, Message } from '@alifd/next' 22 | 23 | const SchemaField = createSchemaField({ 24 | components: { 25 | FormItem, 26 | Editable, 27 | Input, 28 | ArrayTable, 29 | }, 30 | }) 31 | 32 | const form = createForm() 33 | 34 | const range = (count: number) => 35 | Array.from(new Array(count)).map((_, key) => ({ 36 | aaa: key, 37 | })) 38 | 39 | export default () => { 40 | return ( 41 | <FormProvider form={form}> 42 | <SchemaField> 43 | <SchemaField.Array 44 | name="array" 45 | x-decorator="FormItem" 46 | x-component="ArrayTable" 47 | x-component-props={{ 48 | pagination: { pageSize: 10 }, 49 | style: { width: '100%' }, 50 | }} 51 | > 52 | <SchemaField.Object> 53 | <SchemaField.Void 54 | x-component="ArrayTable.Column" 55 | x-component-props={{ width: 80, title: 'Sort', align: 'center' }} 56 | > 57 | <SchemaField.Void 58 | x-decorator="FormItem" 59 | required 60 | x-component="ArrayTable.SortHandle" 61 | /> 62 | </SchemaField.Void> 63 | <SchemaField.Void 64 | x-component="ArrayTable.Column" 65 | x-component-props={{ 66 | width: 120, 67 | title: 'Index', 68 | align: 'center', 69 | }} 70 | > 71 | <SchemaField.Void 72 | x-decorator="FormItem" 73 | required 74 | x-component="ArrayTable.Index" 75 | /> 76 | </SchemaField.Void> 77 | <SchemaField.Void 78 | x-component="ArrayTable.Column" 79 | x-component-props={{ title: 'A1', dataIndex: 'a1', width: 200 }} 80 | > 81 | <SchemaField.String 82 | name="a1" 83 | x-decorator="Editable" 84 | required 85 | x-component="Input" 86 | /> 87 | </SchemaField.Void> 88 | <SchemaField.Void 89 | x-component="ArrayTable.Column" 90 | x-component-props={{ title: 'A2', width: 200 }} 91 | > 92 | <SchemaField.String 93 | x-decorator="FormItem" 94 | name="a2" 95 | required 96 | x-component="Input" 97 | /> 98 | </SchemaField.Void> 99 | <SchemaField.Void 100 | x-component="ArrayTable.Column" 101 | x-component-props={{ title: 'A3', width: 200 }} 102 | > 103 | <SchemaField.String 104 | x-decorator="FormItem" 105 | name="a3" 106 | required 107 | x-component="Input" 108 | /> 109 | </SchemaField.Void> 110 | <SchemaField.Void 111 | x-component="ArrayTable.Column" 112 | x-component-props={{ 113 | title: 'Operations', 114 | dataIndex: 'operations', 115 | width: 200, 116 | fixed: 'right', 117 | }} 118 | > 119 | <SchemaField.Void x-component="FormItem"> 120 | <SchemaField.Void x-component="ArrayTable.Remove" /> 121 | <SchemaField.Void x-component="ArrayTable.MoveDown" /> 122 | <SchemaField.Void x-component="ArrayTable.MoveUp" /> 123 | </SchemaField.Void> 124 | </SchemaField.Void> 125 | </SchemaField.Object> 126 | <SchemaField.Void 127 | x-component="ArrayTable.Addition" 128 | title="Add entry" 129 | /> 130 | </SchemaField.Array> 131 | </SchemaField> 132 | <FormButtonGroup> 133 | <Submit onSubmit={console.log}>Submit</Submit> 134 | <Button 135 | onClick={() => { 136 | form.setInitialValues({ 137 | array: range(100000), 138 | }) 139 | }} 140 | > 141 | Load 10W pieces of large data 142 | </Button> 143 | </FormButtonGroup> 144 | <Message style={{ marginTop: 10 }} type="warning"> 145 | Note: Open the formily plug-in page, because there is data communication 146 | in the background, which will occupy the browser's computing power, it 147 | is best to test in the incognito mode (without the formily plug-in) 148 | </Message> 149 | </FormProvider> 150 | ) 151 | } 152 | ``` 153 | 154 | ## JSON Schema case 155 | 156 | ```tsx 157 | import React from 'react' 158 | import { 159 | FormItem, 160 | Input, 161 | ArrayTable, 162 | Editable, 163 | FormButtonGroup, 164 | Submit, 165 | } from '@formily/next' 166 | import { createForm } from '@formily/core' 167 | import { FormProvider, createSchemaField } from '@formily/react' 168 | 169 | const SchemaField = createSchemaField({ 170 | components: { 171 | FormItem, 172 | Editable, 173 | Input, 174 | ArrayTable, 175 | }, 176 | }) 177 | 178 | const form = createForm() 179 | 180 | const schema = { 181 | type: 'object', 182 | properties: { 183 | array: { 184 | type: 'array', 185 | 'x-decorator': 'FormItem', 186 | 'x-component': 'ArrayTable', 187 | 'x-component-props': { 188 | pagination: { pageSize: 10 }, 189 | style: { width: '100%' }, 190 | }, 191 | items: { 192 | type: 'object', 193 | properties: { 194 | column1: { 195 | type: 'void', 196 | 'x-component': 'ArrayTable.Column', 197 | 'x-component-props': { width: 80, title: 'Sort', align: 'center' }, 198 | properties: { 199 | sort: { 200 | type: 'void', 201 | 'x-component': 'ArrayTable.SortHandle', 202 | }, 203 | }, 204 | }, 205 | column2: { 206 | type: 'void', 207 | 'x-component': 'ArrayTable.Column', 208 | 'x-component-props': { 209 | width: 120, 210 | title: 'Index', 211 | align: 'center', 212 | }, 213 | properties: { 214 | index: { 215 | type: 'void', 216 | 'x-component': 'ArrayTable.Index', 217 | }, 218 | }, 219 | }, 220 | column3: { 221 | type: 'void', 222 | 'x-component': 'ArrayTable.Column', 223 | 'x-component-props': { width: 200, title: 'A1' }, 224 | properties: { 225 | a1: { 226 | type: 'string', 227 | 'x-decorator': 'Editable', 228 | 'x-component': 'Input', 229 | }, 230 | }, 231 | }, 232 | column4: { 233 | type: 'void', 234 | 'x-component': 'ArrayTable.Column', 235 | 'x-component-props': { width: 200, title: 'A2' }, 236 | properties: { 237 | a2: { 238 | type: 'string', 239 | 'x-decorator': 'FormItem', 240 | 'x-component': 'Input', 241 | }, 242 | }, 243 | }, 244 | column5: { 245 | type: 'void', 246 | 'x-component': 'ArrayTable.Column', 247 | 'x-component-props': { width: 200, title: 'A3' }, 248 | properties: { 249 | a3: { 250 | type: 'string', 251 | 'x-decorator': 'FormItem', 252 | 'x-component': 'Input', 253 | }, 254 | }, 255 | }, 256 | column6: { 257 | type: 'void', 258 | 'x-component': 'ArrayTable.Column', 259 | 'x-component-props': { 260 | title: 'Operations', 261 | dataIndex: 'operations', 262 | width: 200, 263 | fixed: 'right', 264 | }, 265 | properties: { 266 | item: { 267 | type: 'void', 268 | 'x-component': 'FormItem', 269 | properties: { 270 | remove: { 271 | type: 'void', 272 | 'x-component': 'ArrayTable.Remove', 273 | }, 274 | moveDown: { 275 | type: 'void', 276 | 'x-component': 'ArrayTable.MoveDown', 277 | }, 278 | moveUp: { 279 | type: 'void', 280 | 'x-component': 'ArrayTable.MoveUp', 281 | }, 282 | }, 283 | }, 284 | }, 285 | }, 286 | }, 287 | }, 288 | properties: { 289 | add: { 290 | type: 'void', 291 | 'x-component': 'ArrayTable.Addition', 292 | title: 'Add entry', 293 | }, 294 | }, 295 | }, 296 | }, 297 | } 298 | 299 | export default () => { 300 | return ( 301 | <FormProvider form={form}> 302 | <SchemaField schema={schema} /> 303 | <FormButtonGroup> 304 | <Submit onSubmit={console.log}>Submit</Submit> 305 | </FormButtonGroup> 306 | </FormProvider> 307 | ) 308 | } 309 | ``` 310 | 311 | ## Effects linkage case 312 | 313 | ```tsx 314 | import React from 'react' 315 | import { 316 | FormItem, 317 | Input, 318 | ArrayTable, 319 | Switch, 320 | FormButtonGroup, 321 | Submit, 322 | } from '@formily/next' 323 | import { createForm, onFieldChange, onFieldReact } from '@formily/core' 324 | import { FormProvider, createSchemaField } from '@formily/react' 325 | import { Button } from '@alifd/next' 326 | 327 | const SchemaField = createSchemaField({ 328 | components: { 329 | FormItem, 330 | Switch, 331 | Input, 332 | Button, 333 | ArrayTable, 334 | }, 335 | }) 336 | 337 | const form = createForm({ 338 | effects: () => { 339 | //Active linkage mode 340 | onFieldChange('hideFirstColumn', ['value'], (field) => { 341 | field.query('array.column4').take((target) => { 342 | target.visible = !field.value 343 | }) 344 | field.query('array.*.a2').take((target) => { 345 | target.visible = !field.value 346 | }) 347 | }) 348 | //Passive linkage mode 349 | onFieldReact('array.*.a2', (field) => { 350 | field.visible = !field.query('.a1').get('value') 351 | }) 352 | }, 353 | }) 354 | 355 | export default () => { 356 | return ( 357 | <FormProvider form={form}> 358 | <SchemaField> 359 | <SchemaField.Boolean 360 | name="hideFirstColumn" 361 | x-decorator="FormItem" 362 | x-component="Switch" 363 | title="Hide A2" 364 | /> 365 | <SchemaField.Array 366 | name="array" 367 | x-decorator="FormItem" 368 | x-component="ArrayTable" 369 | x-component-props={{ 370 | pagination: { pageSize: 10 }, 371 | style: { width: '100%' }, 372 | }} 373 | > 374 | <SchemaField.Object> 375 | <SchemaField.Void 376 | x-component="ArrayTable.Column" 377 | name="column1" 378 | x-component-props={{ width: 80, title: 'Sort', align: 'center' }} 379 | > 380 | <SchemaField.Void 381 | x-decorator="FormItem" 382 | required 383 | x-component="ArrayTable.SortHandle" 384 | /> 385 | </SchemaField.Void> 386 | <SchemaField.Void 387 | x-component="ArrayTable.Column" 388 | name="column2" 389 | x-component-props={{ 390 | width: 120, 391 | title: 'Index', 392 | align: 'center', 393 | }} 394 | > 395 | <SchemaField.String 396 | x-decorator="FormItem" 397 | required 398 | x-component="ArrayTable.Index" 399 | /> 400 | </SchemaField.Void> 401 | <SchemaField.Void 402 | x-component="ArrayTable.Column" 403 | name="column3" 404 | x-component-props={{ 405 | title: 'Explicitly hidden->A2', 406 | dataIndex: 'a1', 407 | width: 100, 408 | }} 409 | > 410 | <SchemaField.Boolean 411 | name="a1" 412 | x-decorator="FormItem" 413 | required 414 | x-component="Switch" 415 | /> 416 | </SchemaField.Void> 417 | <SchemaField.Void 418 | x-component="ArrayTable.Column" 419 | name="column4" 420 | x-component-props={{ title: 'A2', width: 200 }} 421 | > 422 | <SchemaField.String 423 | x-decorator="FormItem" 424 | name="a2" 425 | required 426 | x-component="Input" 427 | /> 428 | </SchemaField.Void> 429 | <SchemaField.Void 430 | x-component="ArrayTable.Column" 431 | name="column5" 432 | x-component-props={{ title: 'A3', width: 200 }} 433 | > 434 | <SchemaField.String 435 | x-decorator="FormItem" 436 | name="a3" 437 | required 438 | x-component="Input" 439 | /> 440 | </SchemaField.Void> 441 | <SchemaField.Void 442 | x-component="ArrayTable.Column" 443 | name="column6" 444 | x-component-props={{ 445 | title: 'Operations', 446 | dataIndex: 'operations', 447 | width: 200, 448 | fixed: 'right', 449 | }} 450 | > 451 | <SchemaField.Void x-component="FormItem"> 452 | <SchemaField.Void x-component="ArrayTable.Remove" /> 453 | <SchemaField.Void x-component="ArrayTable.MoveDown" /> 454 | <SchemaField.Void x-component="ArrayTable.MoveUp" /> 455 | </SchemaField.Void> 456 | </SchemaField.Void> 457 | </SchemaField.Object> 458 | <SchemaField.Void 459 | x-component="ArrayTable.Addition" 460 | title="Add entry" 461 | /> 462 | </SchemaField.Array> 463 | </SchemaField> 464 | <FormButtonGroup> 465 | <Submit onSubmit={console.log}>Submit</Submit> 466 | </FormButtonGroup> 467 | </FormProvider> 468 | ) 469 | } 470 | ``` 471 | 472 | ## JSON Schema linkage case 473 | 474 | ```tsx 475 | import React from 'react' 476 | import { 477 | FormItem, 478 | Input, 479 | ArrayTable, 480 | Switch, 481 | FormButtonGroup, 482 | Submit, 483 | } from '@formily/next' 484 | import { createForm } from '@formily/core' 485 | import { FormProvider, createSchemaField } from '@formily/react' 486 | 487 | const SchemaField = createSchemaField({ 488 | components: { 489 | FormItem, 490 | Switch, 491 | Input, 492 | ArrayTable, 493 | }, 494 | }) 495 | 496 | const form = createForm() 497 | 498 | const schema = { 499 | type: 'object', 500 | properties: { 501 | hideFirstColumn: { 502 | type: 'boolean', 503 | title: 'Hide A2', 504 | 'x-decorator': 'FormItem', 505 | 'x-component': 'Switch', 506 | }, 507 | array: { 508 | type: 'array', 509 | 'x-decorator': 'FormItem', 510 | 'x-component': 'ArrayTable', 511 | 'x-component-props': { 512 | pagination: { pageSize: 10 }, 513 | style: { width: '100%' }, 514 | }, 515 | items: { 516 | type: 'object', 517 | properties: { 518 | column1: { 519 | type: 'void', 520 | 'x-component': 'ArrayTable.Column', 521 | 'x-component-props': { width: 80, title: 'Sort', align: 'center' }, 522 | 523 | properties: { 524 | sort: { 525 | type: 'void', 526 | 'x-component': 'ArrayTable.SortHandle', 527 | }, 528 | }, 529 | }, 530 | column2: { 531 | type: 'void', 532 | 'x-component': 'ArrayTable.Column', 533 | 'x-component-props': { 534 | width: 120, 535 | title: 'Index', 536 | align: 'center', 537 | }, 538 | properties: { 539 | index: { 540 | type: 'void', 541 | 'x-component': 'ArrayTable.Index', 542 | }, 543 | }, 544 | }, 545 | column3: { 546 | type: 'void', 547 | 'x-component': 'ArrayTable.Column', 548 | 'x-component-props': { width: 100, title: 'Explicitly hidden->A2' }, 549 | properties: { 550 | a1: { 551 | type: 'boolean', 552 | 'x-decorator': 'FormItem', 553 | 'x-component': 'Switch', 554 | }, 555 | }, 556 | }, 557 | column4: { 558 | type: 'void', 559 | 'x-component': 'ArrayTable.Column', 560 | 'x-component-props': { width: 200, title: 'A2' }, 561 | 'x-reactions': [ 562 | { 563 | dependencies: ['hideFirstColumn'], 564 | when: '{{$deps[0]}}', 565 | fulfill: { 566 | schema: { 567 | 'x-visible': false, 568 | }, 569 | }, 570 | otherwise: { 571 | schema: { 572 | 'x-visible': true, 573 | }, 574 | }, 575 | }, 576 | ], 577 | properties: { 578 | a2: { 579 | type: 'string', 580 | 'x-decorator': 'FormItem', 581 | 'x-component': 'Input', 582 | required: true, 583 | 'x-reactions': [ 584 | { 585 | dependencies: ['.a1', 'hideFirstColumn'], 586 | when: '{{$deps[1] || $deps[0]}}', 587 | fulfill: { 588 | schema: { 589 | 'x-visible': false, 590 | }, 591 | }, 592 | otherwise: { 593 | schema: { 594 | 'x-visible': true, 595 | }, 596 | }, 597 | }, 598 | ], 599 | }, 600 | }, 601 | }, 602 | column5: { 603 | type: 'void', 604 | 'x-component': 'ArrayTable.Column', 605 | 'x-component-props': { width: 200, title: 'A3' }, 606 | properties: { 607 | a3: { 608 | type: 'string', 609 | required: true, 610 | 'x-decorator': 'FormItem', 611 | 'x-component': 'Input', 612 | }, 613 | }, 614 | }, 615 | column6: { 616 | type: 'void', 617 | 'x-component': 'ArrayTable.Column', 618 | 'x-component-props': { 619 | title: 'Operations', 620 | dataIndex: 'operations', 621 | width: 200, 622 | fixed: 'right', 623 | }, 624 | properties: { 625 | item: { 626 | type: 'void', 627 | 'x-component': 'FormItem', 628 | properties: { 629 | remove: { 630 | type: 'void', 631 | 'x-component': 'ArrayTable.Remove', 632 | }, 633 | moveDown: { 634 | type: 'void', 635 | 'x-component': 'ArrayTable.MoveDown', 636 | }, 637 | moveUp: { 638 | type: 'void', 639 | 'x-component': 'ArrayTable.MoveUp', 640 | }, 641 | }, 642 | }, 643 | }, 644 | }, 645 | }, 646 | }, 647 | properties: { 648 | add: { 649 | type: 'void', 650 | 'x-component': 'ArrayTable.Addition', 651 | title: 'Add entry', 652 | }, 653 | }, 654 | }, 655 | }, 656 | } 657 | 658 | export default () => { 659 | return ( 660 | <FormProvider form={form}> 661 | <SchemaField schema={schema} /> 662 | <FormButtonGroup> 663 | <Submit onSubmit={console.log}>Submit</Submit> 664 | </FormButtonGroup> 665 | </FormProvider> 666 | ) 667 | } 668 | ``` 669 | 670 | ## API 671 | 672 | ### ArrayTable 673 | 674 | > Form Components 675 | 676 | Extended attributes 677 | 678 | | Property name | Type | Description | Default value | 679 | | ------------- | ------------------------- | --------------- | ------------- | 680 | | onAdd | `(index: number) => void` | add method | | 681 | | onRemove | `(index: number) => void` | remove method | | 682 | | onCopy | `(index: number) => void` | copy method | | 683 | | onMoveUp | `(index: number) => void` | moveUp method | | 684 | | onMoveDown | `(index: number) => void` | moveDown method | | 685 | 686 | Other Reference https://fusion.design/pc/component/basic/table 687 | 688 | ### ArrayTable.Column 689 | 690 | > Table Column 691 | 692 | Reference https://fusion.design/pc/component/basic/table 693 | 694 | ### ArrayTable.SortHandle 695 | 696 | > Drag handle 697 | 698 | Reference https://ant.design/components/icon-cn/ 699 | 700 | ### ArrayTable.Addition 701 | 702 | > Add button 703 | 704 | Extended attributes 705 | 706 | | Property name | Type | Description | Default value | 707 | | ------------- | -------------------- | ------------- | ------------- | 708 | | title | ReactText | Copywriting | | 709 | | method | `'push' \|'unshift'` | add method | `'push'` | 710 | | defaultValue | `any` | Default value | | 711 | 712 | Other references https://fusion.design/pc/component/basic/button 713 | 714 | Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective 715 | 716 | ### ArrayTable.Remove 717 | 718 | > Delete button 719 | 720 | | Property name | Type | Description | Default value | 721 | | ------------- | --------- | ----------- | ------------- | 722 | | title | ReactText | Copywriting | | 723 | 724 | Other references https://ant.design/components/icon-cn/ 725 | 726 | Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective 727 | 728 | ### ArrayTable.MoveDown 729 | 730 | > Move down button 731 | 732 | | Property name | Type | Description | Default value | 733 | | ------------- | --------- | ----------- | ------------- | 734 | | title | ReactText | Copywriting | | 735 | 736 | Other references https://ant.design/components/icon-cn/ 737 | 738 | Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective 739 | 740 | ### ArrayTable.MoveUp 741 | 742 | > Move up button 743 | 744 | | Property name | Type | Description | Default value | 745 | | ------------- | --------- | ----------- | ------------- | 746 | | title | ReactText | Copywriting | | 747 | 748 | Other references https://ant.design/components/icon-cn/ 749 | 750 | Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective 751 | 752 | ### ArrayTable.Index 753 | 754 | > Index Renderer 755 | 756 | No attributes 757 | 758 | ### ArrayTable.useIndex 759 | 760 | > Read the React Hook of the current rendering row index 761 | 762 | ### ArrayTable.useRecord 763 | 764 | > Read the React Hook of the current rendering row 765 | ```