diff --git a/.eslintrc b/.eslintrc index 72b7088..ba0b49f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,7 +5,7 @@ "extends": [ "plugin:react/recommended", "plugin:@typescript-eslint/recommended", - "prettier/@typescript-eslint" + "prettier" ], "globals": { "sleep": true, diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..958784c --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,5 @@ +{ + "default": true, + "MD033": false, + "MD013": false +} diff --git a/.umirc.js b/.umirc.js deleted file mode 100644 index 29241dd..0000000 --- a/.umirc.js +++ /dev/null @@ -1,82 +0,0 @@ -import { resolve } from 'path' -export default { - mode: 'site', - logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg', - title: 'Ant Design', - hash: true, - favicon: - '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg', - outputPath: './doc-site', - locales: [ - ['en-US', 'English'], - ['zh-CN', '中文'], - ], - navs: { - 'zh-CN': [ - { - title: 'Ant Design', - path: '/zh-CN/components', - }, - { - title: '主站', - path: 'https://formilyjs.org', - }, - { - title: 'GITHUB', - path: 'https://github.com/alibaba/formily', - }, - ], - 'en-US': [ - { - title: 'Ant Design', - path: '/components', - }, - { - title: 'Home Site', - path: 'https://formilyjs.org', - }, - { - title: 'GITHUB', - path: 'https://github.com/alibaba/formily', - }, - ], - }, - links: [ - { - rel: 'stylesheet', - href: 'https://unpkg.com/antd/dist/antd.css', - }, - ], - styles: [ - `.__dumi-default-navbar-logo{ - background-size: 140px!important; - background-position: center left!important; - background-repeat: no-repeat!important; - padding-left: 150px!important;/*可根据title的宽度调整*/ - font-size: 22px!important; - color: #000!important; - font-weight: lighter!important; - } - .__dumi-default-navbar{ - padding: 0 28px !important; - } - .__dumi-default-layout-hero{ - background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png); - background-size: cover; - background-repeat: no-repeat; - padding: 120px 0 !important; - } - .__dumi-default-layout-hero h1{ - color:#45124e !important; - font-size:80px !important; - padding-bottom: 30px !important; - } - .__dumi-default-dark-switch { - display:none - } - nav a{ - text-decoration: none !important; - } - `, - ], -} diff --git a/.umirc.ts b/.umirc.ts new file mode 100644 index 0000000..5d80963 --- /dev/null +++ b/.umirc.ts @@ -0,0 +1,164 @@ +export default { + mode: 'site', + logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg', + title: 'Ant Design V5', + hash: true, + favicon: + '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg', + outputPath: './doc-site', + locales: [ + ['en-US', 'English'], + ['zh-CN', '中文'], + ], + navs: { + 'zh-CN': [ + { + title: 'Ant Design V5', + path: '/zh-CN/components', + }, + { + title: '主站', + path: 'https://v2.formilyjs.org/', + }, + { + title: 'GITHUB', + path: 'https://github.com/formilyjs/antd', + }, + ], + 'en-US': [ + { + title: 'Ant Design V5', + path: '/components', + }, + { + title: 'Home Site', + path: 'https://formilyjs.org', + }, + { + title: 'GITHUB', + path: 'https://github.com/alibaba/formily', + }, + ], + }, + + headScripts: [ + ` + function loadAd(){ + var header = document.querySelector('.__dumi-default-layout-content .markdown h1') + if(header && !header.querySelector('#_carbonads_js')){ + var script = document.createElement('script') + script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg' + script.id = '_carbonads_js' + script.classList.add('head-ad') + header.appendChild(script) + } + } + var request = null + var observer = new MutationObserver(function(){ + cancelIdleCallback(request) + request = requestIdleCallback(loadAd) + }) + document.addEventListener('DOMContentLoaded',function(){ + loadAd() + observer.observe( + document.body, + { + childList:true, + subtree:true + } + ) + }) + `, + ], + styles: [ + `.__dumi-default-navbar-logo{ + height: 60px !important; + width: 150px !important; + padding-left:0 !important; + color: transparent !important; + } + .__dumi-default-navbar{ + padding: 0 28px !important; + } + .__dumi-default-layout-hero{ + background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png); + background-size: cover; + background-repeat: no-repeat; + padding: 120px 0 !important; + } + .__dumi-default-layout-hero h1{ + color:#45124e !important; + font-size:80px !important; + padding-bottom: 30px !important; + } + .__dumi-default-dark-switch { + display:none + } + nav a{ + text-decoration: none !important; + } + #carbonads * { + margin: initial; + padding: initial; + } + #carbonads { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, + sans-serif; + } + #carbonads { + display: flex; + max-width: 330px; + background-color: hsl(0, 0%, 98%); + box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1); + z-index: 100; + float:right; + } + #carbonads a { + color: inherit; + text-decoration: none; + } + #carbonads a:hover { + color: inherit; + } + #carbonads span { + position: relative; + display: block; + overflow: hidden; + } + #carbonads .carbon-wrap { + display: flex; + } + #carbonads .carbon-img { + display: block; + margin: 0; + line-height: 1; + } + #carbonads .carbon-img img { + display: block; + } + #carbonads .carbon-text { + font-size: 13px; + padding: 10px; + margin-bottom: 16px; + line-height: 1.5; + text-align: left; + } + #carbonads .carbon-poweredby { + display: block; + padding: 6px 8px; + background: #f1f1f2; + text-align: center; + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; + font-size: 8px; + line-height: 1; + border-top-left-radius: 3px; + position: absolute; + bottom: 0; + right: 0; + } + `, + ], +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ad92582 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} diff --git a/README.md b/README.md index 4cc5dc7..d7ba574 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# formily antd repository + English | [简体中文](./README.zh-CN.md)

@@ -35,7 +37,7 @@ The Awesome Components Library with Formily & Ant Design. ## WebSite -https://antd.formilyjs.org + ## Community diff --git a/docs/components/ArrayCards.md b/docs/components/ArrayCards.md index 9426855..f9da793 100644 --- a/docs/components/ArrayCards.md +++ b/docs/components/ArrayCards.md @@ -51,6 +51,7 @@ export default () => { x-component="Input" /> + @@ -436,9 +437,9 @@ export default () => { ## API -### ArrayCards +### ArrayCards API -Reference https://ant.design/components/card-cn/ +Reference ### ArrayCards.Addition @@ -452,7 +453,22 @@ Extended attributes | method | `'push' \|'unshift'` | add method | `'push'` | | defaultValue | `any` | Default value | | -Other references https://ant.design/components/button-cn/ +Other references + +Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective + +### ArrayCards.Copy + +> Copy button + +Extended attributes + +| Property name | Type | Description | Default value | +| ------------- | -------------------- | ----------- | ------------- | +| title | ReactText | Copywriting | | +| method | `'push' \|'unshift'` | Copy method | `'push'` | + +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -464,7 +480,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -476,7 +492,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -488,7 +504,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective diff --git a/docs/components/ArrayCards.zh-CN.md b/docs/components/ArrayCards.zh-CN.md index 25862f3..0be323e 100644 --- a/docs/components/ArrayCards.zh-CN.md +++ b/docs/components/ArrayCards.zh-CN.md @@ -51,6 +51,7 @@ export default () => { x-component="Input" /> + @@ -436,9 +437,9 @@ export default () => { ## API -### ArrayCards +### ArrayCards API -参考 https://ant.design/components/card-cn/ +参考 ### ArrayCards.Addition @@ -452,7 +453,22 @@ export default () => { | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | | defaultValue | `any` | 默认值 | | -其余参考 https://ant.design/components/button-cn/ +其余参考 + +注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 + +### ArrayCards.Copy + +> 复制按钮 + +扩展属性 + +| 属性名 | 类型 | 描述 | 默认值 | +| ------ | --------------------- | -------- | -------- | +| title | ReactText | 文案 | | +| method | `'push' \| 'unshift'` | 添加方式 | `'push'` | + +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -464,7 +480,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -476,7 +492,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -488,7 +504,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 diff --git a/docs/components/ArrayCollapse.md b/docs/components/ArrayCollapse.md index c5ed0e2..713da7b 100644 --- a/docs/components/ArrayCollapse.md +++ b/docs/components/ArrayCollapse.md @@ -556,13 +556,13 @@ export default () => { ## API -### ArrayCollapse +### ArrayCollapse API -Reference https://ant.design/components/collapse-cn/ +Reference ### ArrayCollapse.CollapsePanel -Reference https://ant.design/components/collapse-cn/ +Reference ### ArrayCollapse.Addition @@ -576,7 +576,7 @@ Extended attributes | method | `'push' \|'unshift'` | add method | `'push'` | | defaultValue | `any` | Default value | | -Other references https://ant.design/components/button-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -588,7 +588,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -600,7 +600,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -612,7 +612,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective diff --git a/docs/components/ArrayCollapse.zh-CN.md b/docs/components/ArrayCollapse.zh-CN.md index f2e21e8..669922a 100644 --- a/docs/components/ArrayCollapse.zh-CN.md +++ b/docs/components/ArrayCollapse.zh-CN.md @@ -556,13 +556,13 @@ export default () => { ## API -### ArrayCollapse +### ArrayCollapse API -参考 https://ant.design/components/collapse-cn/ +参考 ### ArrayCollapse.CollapsePanel -参考 https://ant.design/components/collapse-cn/ +参考 ### ArrayCollapse.Addition @@ -576,7 +576,7 @@ export default () => { | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | | defaultValue | `any` | 默认值 | | -其余参考 https://ant.design/components/button-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -588,7 +588,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -600,7 +600,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -612,7 +612,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 diff --git a/docs/components/ArrayItems.md b/docs/components/ArrayItems.md index ba20455..49d04ee 100644 --- a/docs/components/ArrayItems.md +++ b/docs/components/ArrayItems.md @@ -61,6 +61,10 @@ export default () => { x-decorator="FormItem" x-component="ArrayItems.Remove" /> + { ## API -### ArrayItems +### ArrayItems API Inherit HTMLDivElement Props @@ -716,7 +720,7 @@ Extended attributes > Drag handle -Reference https://ant.design/components/icon-cn/ +Reference ### ArrayItems.Addition @@ -730,11 +734,26 @@ Extended attributes | method | `'push' \|'unshift'` | add method | `'push'` | | defaultValue | `any` | Default value | | -Other references https://ant.design/components/button-cn/ +Other references + +Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective + +### ArrayItems.Copy + +> Copy button + +Extended attributes + +| Property name | Type | Description | Default value | +| ------------- | -------------------- | ----------- | ------------- | +| title | ReactText | Copywriting | | +| method | `'push' \|'unshift'` | Copy method | `'push'` | + +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective -### ArrayItems.Remove +### ArrayItems.RemoveØ > Delete button @@ -742,7 +761,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -754,7 +773,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -766,7 +785,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective diff --git a/docs/components/ArrayItems.zh-CN.md b/docs/components/ArrayItems.zh-CN.md index b5cdc68..7057fc4 100644 --- a/docs/components/ArrayItems.zh-CN.md +++ b/docs/components/ArrayItems.zh-CN.md @@ -61,6 +61,10 @@ export default () => { x-decorator="FormItem" x-component="ArrayItems.Remove" /> + { x-decorator="FormItem" x-component="ArrayItems.Remove" /> + { ## API -### ArrayItems +### ArrayItems API 继承 HTMLDivElement Props @@ -713,11 +721,11 @@ export default () => { > 拖拽手柄 -参考 https://ant.design/components/icon-cn/ +参考 ### ArrayItems.Addition -> 添加按钮 +> 添加按钮 Ø 扩展属性 @@ -727,7 +735,22 @@ export default () => { | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | | defaultValue | `any` | 默认值 | | -其余参考 https://ant.design/components/button-cn/ +其余参考 + +注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 + +### ArrayItems.Copy + +> 复制按钮 + +扩展属性 + +| 属性名 | 类型 | 描述 | 默认值 | +| ------ | --------------------- | -------- | -------- | +| title | ReactText | 文案 | | +| method | `'push' \| 'unshift'` | 添加方式 | `'push'` | + +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -739,7 +762,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -751,7 +774,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -763,7 +786,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 diff --git a/docs/components/ArrayTable.md b/docs/components/ArrayTable.md index 3acf4dd..368f736 100644 --- a/docs/components/ArrayTable.md +++ b/docs/components/ArrayTable.md @@ -654,23 +654,23 @@ export default () => { ## API -### ArrayTable +### ArrayTable API > Form Components -Reference https://ant.design/components/table-cn/ +Reference ### ArrayTable.Column > Table Column -Reference https://ant.design/components/table-cn/ +Reference ### ArrayTable.SortHandle > Drag handle -Reference https://ant.design/components/icon-cn/ +Reference ### ArrayTable.Addition @@ -684,7 +684,7 @@ Extended attributes | method | `'push' \|'unshift'` | add method | `'push'` | | defaultValue | `any` | Default value | | -Other references https://ant.design/components/button-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -696,7 +696,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -708,7 +708,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective @@ -720,7 +720,7 @@ Note: The title attribute can receive the title mapping in the Field model, that | ------------- | --------- | ----------- | ------------- | | title | ReactText | Copywriting | | -Other references https://ant.design/components/icon-cn/ +Other references Note: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective diff --git a/docs/components/ArrayTable.zh-CN.md b/docs/components/ArrayTable.zh-CN.md index 4b23165..5e5bdac 100644 --- a/docs/components/ArrayTable.zh-CN.md +++ b/docs/components/ArrayTable.zh-CN.md @@ -654,23 +654,23 @@ export default () => { ## API -### ArrayTable +### ArrayTable API > 表格组件 -参考 https://ant.design/components/table-cn/ +参考 ### ArrayTable.Column > 表格列 -参考 https://ant.design/components/table-cn/ +参考 ### ArrayTable.SortHandle > 拖拽手柄 -参考 https://ant.design/components/icon-cn/ +参考 ### ArrayTable.Addition @@ -684,7 +684,7 @@ export default () => { | method | `'push' \| 'unshift'` | 添加方式 | `'push'` | | defaultValue | `any` | 默认值 | | -其余参考 https://ant.design/components/button-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -696,7 +696,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -708,7 +708,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 @@ -720,7 +720,7 @@ export default () => { | ------ | --------- | ---- | ------ | | title | ReactText | 文案 | | -其余参考 https://ant.design/components/icon-cn/ +其余参考 注意:title 属性可以接收 Field 模型中的 title 映射,也就是在 Field 上传 title 也是生效的 diff --git a/docs/components/ArrayTabs.md b/docs/components/ArrayTabs.md index d0d01c6..8228122 100644 --- a/docs/components/ArrayTabs.md +++ b/docs/components/ArrayTabs.md @@ -161,6 +161,6 @@ export default () => { ## API -### ArrayTabs +### ArrayTabs API -Reference https://ant.design/components/tabs-cn/ +Reference diff --git a/docs/components/ArrayTabs.zh-CN.md b/docs/components/ArrayTabs.zh-CN.md index ed5d9cc..28aa0c6 100644 --- a/docs/components/ArrayTabs.zh-CN.md +++ b/docs/components/ArrayTabs.zh-CN.md @@ -161,6 +161,6 @@ export default () => { ## API -### ArrayTabs +### ArrayTabs API -参考 https://ant.design/components/tabs-cn/ +参考 diff --git a/docs/components/Cascader.md b/docs/components/Cascader.md index b34ecc4..d9f6a84 100644 --- a/docs/components/Cascader.md +++ b/docs/components/Cascader.md @@ -4,242 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Cascader, - FormItem, - }, -}) - -const useAddress = (pattern: FormPathPattern) => { - const transform = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transform(cities) - const _districts = transform(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) - } - onFieldReact(pattern, (field) => { - field.loading = true - fetch('//unpkg.com/china-location/dist/location.json') - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAddress('address') - }, -}) - -export default () => ( - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Cascader, - FormItem, - }, -}) - -const transformAddress = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transformAddress(cities) - const _districts = transformAddress(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) -} - -const useAsyncDataSource = - (url: string, transform: (data: any) => any) => (field) => { - field.loading = true - fetch(url) - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - } - -const form = createForm() - -const schema = { - type: 'object', - properties: { - address: { - type: 'string', - title: 'Address Selection', - 'x-decorator': 'FormItem', - 'x-component': 'Cascader', - 'x-component-props': { - style: { - width: 240, - }, - }, - 'x-reactions': [ - '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}', - ], - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern } from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { action } from '@formily/reactive' - -const useAddress = (pattern: FormPathPattern) => { - const transform = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transform(cities) - const _districts = transform(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) - } - onFieldReact(pattern, (field) => { - field.loading = true - fetch('//unpkg.com/china-location/dist/location.json') - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAddress('address') - }, -}) - -export default () => ( - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/cascader-cn/ +Reference diff --git a/docs/components/Cascader.zh-CN.md b/docs/components/Cascader.zh-CN.md index c0e5892..50f4520 100644 --- a/docs/components/Cascader.zh-CN.md +++ b/docs/components/Cascader.zh-CN.md @@ -4,242 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Cascader, - FormItem, - }, -}) - -const useAddress = (pattern: FormPathPattern) => { - const transform = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transform(cities) - const _districts = transform(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) - } - onFieldReact(pattern, (field) => { - field.loading = true - fetch('//unpkg.com/china-location/dist/location.json') - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAddress('address') - }, -}) - -export default () => ( - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Cascader, - FormItem, - }, -}) - -const transformAddress = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transformAddress(cities) - const _districts = transformAddress(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) -} - -const useAsyncDataSource = - (url: string, transform: (data: any) => any) => (field) => { - field.loading = true - fetch(url) - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - } - -const form = createForm() - -const schema = { - type: 'object', - properties: { - address: { - type: 'string', - title: '地址选择', - 'x-decorator': 'FormItem', - 'x-component': 'Cascader', - 'x-component-props': { - style: { - width: 240, - }, - }, - 'x-reactions': [ - '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}', - ], - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern } from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { action } from '@formily/reactive' - -const useAddress = (pattern: FormPathPattern) => { - const transform = (data = {}) => { - return Object.entries(data).reduce((buf, [key, value]) => { - if (typeof value === 'string') - return buf.concat({ - label: value, - value: key, - }) - const { name, code, cities, districts } = value - const _cities = transform(cities) - const _districts = transform(districts) - return buf.concat({ - label: name, - value: code, - children: _cities.length - ? _cities - : _districts.length - ? _districts - : undefined, - }) - }, []) - } - onFieldReact(pattern, (field) => { - field.loading = true - fetch('//unpkg.com/china-location/dist/location.json') - .then((res) => res.json()) - .then( - action.bound((data) => { - field.dataSource = transform(data) - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAddress('address') - }, -}) - -export default () => ( - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/cascader-cn/ +参考 diff --git a/docs/components/Checkbox.md b/docs/components/Checkbox.md index bb01044..52a3698 100644 --- a/docs/components/Checkbox.md +++ b/docs/components/Checkbox.md @@ -4,150 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Checkbox, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Checkbox, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - single: { - type: 'boolean', - title: 'Are you sure?', - 'x-decorator': 'FormItem', - 'x-component': 'Checkbox', - }, - multiple: { - type: 'array', - title: 'Check', - enum: [ - { - label: 'Option 1', - value: 1, - }, - { - label: 'Option 2', - value: 2, - }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Checkbox.Group', - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/checkbox-cn/ +Reference diff --git a/docs/components/Checkbox.zh-CN.md b/docs/components/Checkbox.zh-CN.md index 93fcb1e..d215c3c 100644 --- a/docs/components/Checkbox.zh-CN.md +++ b/docs/components/Checkbox.zh-CN.md @@ -4,150 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Checkbox, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Checkbox, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - single: { - type: 'boolean', - title: '是否确认', - 'x-decorator': 'FormItem', - 'x-component': 'Checkbox', - }, - multiple: { - type: 'array', - title: '复选', - enum: [ - { - label: '选项1', - value: 1, - }, - { - label: '选项2', - value: 2, - }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Checkbox.Group', - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/checkbox-cn/ +参考 diff --git a/docs/components/DatePicker.md b/docs/components/DatePicker.md index aa8aae5..b1de1d7 100644 --- a/docs/components/DatePicker.md +++ b/docs/components/DatePicker.md @@ -4,349 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - date: { - title: 'Normal date', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - type: 'string', - }, - week: { - title: 'Week Selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'week', - }, - type: 'string', - }, - month: { - title: 'Month Selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'month', - }, - type: 'string', - }, - quarter: { - title: 'Fiscal Year Selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'quarter', - }, - type: 'string', - }, - year: { - title: 'Year selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'year', - }, - type: 'string', - }, - '[startDate,endDate]': { - title: 'Date range', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - showTime: true, - }, - type: 'string', - }, - range_week: { - title: 'Week range selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'week', - }, - type: 'string', - }, - range_month: { - title: 'Month Range Selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'month', - }, - type: 'string', - }, - range_quarter: { - title: 'Financial year range selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'quarter', - }, - type: 'string', - }, - range_year: { - name: 'range_year', - title: 'Year range selection', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'year', - }, - type: 'string', - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - - - - - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/date-picker-cn/ +Reference diff --git a/docs/components/DatePicker.zh-CN.md b/docs/components/DatePicker.zh-CN.md index 4bacca6..17b86ac 100644 --- a/docs/components/DatePicker.zh-CN.md +++ b/docs/components/DatePicker.zh-CN.md @@ -4,349 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - date: { - title: '普通日期', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - type: 'string', - }, - week: { - title: '周选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'week', - }, - type: 'string', - }, - month: { - title: '月选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'month', - }, - type: 'string', - }, - quarter: { - title: '财年选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'quarter', - }, - type: 'string', - }, - year: { - title: '年选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - 'x-component-props': { - picker: 'year', - }, - type: 'string', - }, - '[startDate,endDate]': { - title: '日期范围', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - showTime: true, - }, - type: 'string', - }, - range_week: { - title: '周范围选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'week', - }, - type: 'string', - }, - range_month: { - title: '月范围选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'month', - }, - type: 'string', - }, - range_quarter: { - title: '财年范围选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'quarter', - }, - type: 'string', - }, - range_year: { - name: 'range_year', - title: '年范围选择', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker.RangePicker', - 'x-component-props': { - picker: 'year', - }, - type: 'string', - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - - - - - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/date-picker-cn/ +参考 diff --git a/docs/components/Editable.md b/docs/components/Editable.md index 3873753..74ae7b2 100644 --- a/docs/components/Editable.md +++ b/docs/components/Editable.md @@ -6,282 +6,26 @@ ## Markup Schema example -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - Editable, - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - { - field.title = field.query('.void.date2').get('value') || field.title - }} - > - - - - { - field.title = field.value?.date || field.title - }} - > - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - Editable, - Input, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - date: { - type: 'string', - title: 'Date', - 'x-decorator': 'Editable', - 'x-component': 'DatePicker', - }, - input: { - type: 'string', - title: 'input box', - 'x-decorator': 'Editable', - 'x-component': 'Input', - }, - void: { - type: 'void', - title: 'Virtual Node Container', - 'x-component': 'Editable.Popover', - 'x-reactions': - "{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}", - properties: { - date2: { - type: 'string', - title: 'Date', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - }, - input2: { - type: 'string', - title: 'input box', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, - }, - }, - iobject: { - type: 'object', - title: 'Object node container', - 'x-component': 'Editable.Popover', - 'x-reactions': - '{{(field) => field.title = field.value && field.value.date || field.title}}', - properties: { - date: { - type: 'string', - title: 'Date', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - }, - input: { - type: 'string', - title: 'input box', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, - }, - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field, VoidField, ObjectField } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - { - field.title = field.query('.void.date2').get('value') || field.title - }} - component={[Editable.Popover]} - > - - - - { - field.title = field.value?.date || field.title - }} - component={[Editable.Popover]} - > - - - - - - Submit - - -) -``` + ## API -### Editable +### Editable API > Inline editing -Refer to the FormItem property in https://ant.design/components/form-cn/ +Refer to the FormItem property in ### Editable.Popover > Floating layer editing -Reference https://ant.design/components/popover-cn/ +Reference diff --git a/docs/components/Editable.zh-CN.md b/docs/components/Editable.zh-CN.md index 21ed6bf..4cd13b8 100644 --- a/docs/components/Editable.zh-CN.md +++ b/docs/components/Editable.zh-CN.md @@ -6,282 +6,26 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - Editable, - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - { - field.title = field.query('.void.date2').get('value') || field.title - }} - > - - - - { - field.title = field.value?.date || field.title - }} - > - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - DatePicker, - Editable, - Input, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - date: { - type: 'string', - title: '日期', - 'x-decorator': 'Editable', - 'x-component': 'DatePicker', - }, - input: { - type: 'string', - title: '输入框', - 'x-decorator': 'Editable', - 'x-component': 'Input', - }, - void: { - type: 'void', - title: '虚拟节点容器', - 'x-component': 'Editable.Popover', - 'x-reactions': - "{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}", - properties: { - date2: { - type: 'string', - title: '日期', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - }, - input2: { - type: 'string', - title: '输入框', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, - }, - }, - iobject: { - type: 'object', - title: '对象节点容器', - 'x-component': 'Editable.Popover', - 'x-reactions': - '{{(field) => field.title = field.value && field.value.date || field.title}}', - properties: { - date: { - type: 'string', - title: '日期', - 'x-decorator': 'FormItem', - 'x-component': 'DatePicker', - }, - input: { - type: 'string', - title: '输入框', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, - }, - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { - Input, - DatePicker, - Editable, - FormItem, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field, VoidField, ObjectField } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - { - field.title = field.query('.void.date2').get('value') || field.title - }} - component={[Editable.Popover]} - > - - - - { - field.title = field.value?.date || field.title - }} - component={[Editable.Popover]} - > - - - - - - 提交 - - -) -``` + ## API -### Editable +### Editable API > 内联编辑 -参考 https://ant.design/components/form-cn/ 中的 FormItem 属性 +参考 中的 FormItem 属性 ### Editable.Popover > 浮层编辑 -参考 https://ant.design/components/popover-cn/ +参考 diff --git a/docs/components/Form.md b/docs/components/Form.md index 675e4f2..3f4485c 100644 --- a/docs/components/Form.md +++ b/docs/components/Form.md @@ -4,79 +4,7 @@ ## Use Cases -```tsx -import React from 'react' -import { - Input, - Select, - Form, - FormItem, - FormGrid, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { Field } from '@formily/react' - -const form = createForm() - -export default () => ( -

- - - - - - - - Query - - - -) -``` + Note: To realize the carriage return submission, we cannot pass the onSubmit event to it when using the Submit component, otherwise the carriage return submission will become invalid. The purpose of this is to prevent users from writing onSubmit event listeners in multiple places at the same time, and processing logic If they are inconsistent, it is difficult to locate the problem when submitting. diff --git a/docs/components/Form.zh-CN.md b/docs/components/Form.zh-CN.md index d3d3d2a..d570756 100644 --- a/docs/components/Form.zh-CN.md +++ b/docs/components/Form.zh-CN.md @@ -4,79 +4,7 @@ ## 使用案例 -```tsx -import React from 'react' -import { - Input, - Select, - Form, - FormItem, - FormGrid, - FormButtonGroup, - Submit, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { Field } from '@formily/react' - -const form = createForm() - -export default () => ( -
- - - - - - - - 查询 - - -
-) -``` + 注意:想要实现回车提交,我们在使用Submit组件的时候不能给其传onSubmit事件,否则回车提交会失效,这样做的目的是为了防止用户同时在多处写onSubmit事件监听器,处理逻辑不一致的话,提交时很难定位问题。 diff --git a/docs/components/FormButtonGroup.md b/docs/components/FormButtonGroup.md index e3fb258..ced3bf9 100644 --- a/docs/components/FormButtonGroup.md +++ b/docs/components/FormButtonGroup.md @@ -289,7 +289,7 @@ export default () => { ## API -### FormButtonGroup +### FormButtonGroup API > This component is mainly used to handle the button group gap diff --git a/docs/components/FormButtonGroup.zh-CN.md b/docs/components/FormButtonGroup.zh-CN.md index 8773fba..95094d9 100644 --- a/docs/components/FormButtonGroup.zh-CN.md +++ b/docs/components/FormButtonGroup.zh-CN.md @@ -289,7 +289,7 @@ export default () => { ## API -### FormButtonGroup +### FormButtonGroup API > 该组件主要用来处理按钮组间隙 diff --git a/docs/components/FormCollapse.md b/docs/components/FormCollapse.md index 127bba0..febcdc0 100644 --- a/docs/components/FormCollapse.md +++ b/docs/components/FormCollapse.md @@ -232,17 +232,17 @@ export default () => { ## API -### FormCollapse +### FormCollapse API | Property name | Type | Description | Default value | | ------------- | ------------- | --------------------------------------------------------------- | ------------- | | formCollapse | IFormCollapse | Pass in the model created by createFormCollapse/useFormCollapse | | -Other references https://ant.design/components/collapse-cn/ +Other references ### FormCollapse.CollapsePanel -Reference https://ant.design/components/collapse-cn/ +Reference ### FormCollapse.createFormCollapse diff --git a/docs/components/FormCollapse.zh-CN.md b/docs/components/FormCollapse.zh-CN.md index 2e4b3c9..bd8b18c 100644 --- a/docs/components/FormCollapse.zh-CN.md +++ b/docs/components/FormCollapse.zh-CN.md @@ -232,17 +232,17 @@ export default () => { ## API -### FormCollapse +### FormCollapse API | 属性名 | 类型 | 描述 | 默认值 | | ------------ | ------------- | ---------------------------------------------------------- | ------ | | formCollapse | IFormCollapse | 传入通过 createFormCollapse/useFormCollapse 创建出来的模型 | | -其余参考 https://ant.design/components/collapse-cn/ +其余参考 ### FormCollapse.CollapsePanel -参考 https://ant.design/components/collapse-cn/ +参考 ### FormCollapse.createFormCollapse diff --git a/docs/components/FormDialog.md b/docs/components/FormDialog.md index 9dccb2c..d328ea4 100644 --- a/docs/components/FormDialog.md +++ b/docs/components/FormDialog.md @@ -21,7 +21,7 @@ export default () => { return ( - - - - - ) -} -``` - -## API - -### PreviewText.Input - -Reference https://ant.design/components/input-cn/ - -### PreviewText.Select - -Reference https://ant.design/components/select-cn/ - -### PreviewText.TreeSelect - -Reference https://ant.design/components/tree-select-cn/ - -### PreviewText.Cascader - -Reference https://ant.design/components/cascader-cn/ - -### PreviewText.DatePicker - -Reference https://ant.design/components/date-picker-cn/ - -### PreviewText.DateRangePicker - -Reference https://ant.design/components/date-picker-cn/ - -### PreviewText.TimePicker - -Reference https://ant.design/components/time-picker-cn/ - -### PreviewText.TimeRangePicker - -Reference https://ant.design/components/time-picker-cn/ - -### PreviewText.Placeholder - -| Property name | Type | Description | Default value | -| ------------- | ------ | ------------------- | ------------- | -| value | stirng | Default placeholder | N/A | - -### PreviewText.usePlaceholder - -```ts pure -interface usePlaceholder { - (): string -} -``` diff --git a/docs/components/PreviewText.zh-CN.md b/docs/components/PreviewText.zh-CN.md deleted file mode 100644 index 19b0d4d..0000000 --- a/docs/components/PreviewText.zh-CN.md +++ /dev/null @@ -1,249 +0,0 @@ -# PreviewText - -> 阅读态组件,主要用来实现类 Input,类 DatePicker 这些组件的阅读态 - -## 简单用例 - -```tsx -import React from 'react' -import { PreviewText, FormItem, FormLayout } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - FormItem, - PreviewText, - }, -}) - -const form = createForm() - -export default () => { - return ( - - - - - - - - - - - - - ) -} -``` - -## 扩展阅读态 - -```tsx -import React from 'react' -import { - PreviewText, - FormItem, - FormLayout, - FormButtonGroup, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { - FormProvider, - mapReadPretty, - connect, - createSchemaField, -} from '@formily/react' -import { Button, Input as AntdInput } from 'antd' - -const Input = connect(AntdInput, mapReadPretty(PreviewText.Input)) - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - PreviewText, - }, -}) - -const form = createForm() - -export default () => { - return ( - - - - - - - - - - - - - - - - ) -} -``` - -## API - -### PreviewText.Input - -参考 https://ant.design/components/input-cn/ - -### PreviewText.Select - -参考 https://ant.design/components/select-cn/ - -### PreviewText.TreeSelect - -参考 https://ant.design/components/tree-select-cn/ - -### PreviewText.Cascader - -参考 https://ant.design/components/cascader-cn/ - -### PreviewText.DatePicker - -参考 https://ant.design/components/date-picker-cn/ - -### PreviewText.DateRangePicker - -参考 https://ant.design/components/date-picker-cn/ - -### PreviewText.TimePicker - -参考 https://ant.design/components/time-picker-cn/ - -### PreviewText.TimeRangePicker - -参考 https://ant.design/components/time-picker-cn/ - -### PreviewText.Placeholder - -| 属性名 | 类型 | 描述 | 默认值 | -| ------ | ------ | ---------- | ------ | -| value | stirng | 缺省占位符 | N/A | - -### PreviewText.usePlaceholder - -```ts pure -interface usePlaceholder { - (): string -} -``` diff --git a/docs/components/Radio.md b/docs/components/Radio.md index fd2ea1e..9f382b3 100644 --- a/docs/components/Radio.md +++ b/docs/components/Radio.md @@ -4,132 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Radio, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Radio, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - radio: { - type: 'number', - title: 'Single selection', - enum: [ - { - label: 'Option 1', - value: 1, - }, - { - label: 'Option 2', - value: 2, - }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Radio.Group', - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/radio-cn/ +Reference diff --git a/docs/components/Radio.zh-CN.md b/docs/components/Radio.zh-CN.md index ee67f0a..ce67803 100644 --- a/docs/components/Radio.zh-CN.md +++ b/docs/components/Radio.zh-CN.md @@ -4,132 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Radio, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Radio, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - radio: { - type: 'number', - title: '单选', - enum: [ - { - label: '选项1', - value: 1, - }, - { - label: '选项2', - value: 2, - }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Radio.Group', - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/radio-cn/ +参考 diff --git a/docs/components/Reset.md b/docs/components/Reset.md index be98a26..6a4a5a5 100644 --- a/docs/components/Reset.md +++ b/docs/components/Reset.md @@ -6,186 +6,28 @@ > Controls with default values cannot be cleared -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Reset - - -) -``` + ## Force empty reset -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Reset - - -) -``` + ## Reset and verify -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Reset - - -) -``` + ## Force empty reset and verify -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - Reset - - - -) -``` + ## API -### Reset +### Reset API -Other API reference https://ant.design/components/button-cn/ +Other API reference | Property name | Type | Description | Default value | | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | ------------- | -| onClick | `(event: MouseEvent) => void \| boolean` | Click event, if it returns false, it can block resetting | - | +| onClick | `(event: MouseEvent) => void \|boolean` | Click event, if it returns false, it can block resetting | - | | onResetValidateSuccess | (payload: any) => void | Reset validation success event | - | | onResetValidateFailed | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Reset validation failure event | - | diff --git a/docs/components/Reset.zh-CN.md b/docs/components/Reset.zh-CN.md index 5b28210..8a7130f 100644 --- a/docs/components/Reset.zh-CN.md +++ b/docs/components/Reset.zh-CN.md @@ -6,186 +6,28 @@ > 有默认值的控件无法被清空 -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 重置 - - -) -``` + ## 强制清空重置 -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 重置 - - -) -``` + ## 重置并校验 -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 重置 - - -) -``` + ## 强制清空重置并校验 -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - 重置 - - - -) -``` + ## API -### Reset +### Reset API -其余 API 参考 https://ant.design/components/button-cn/ +其余 API 参考 | 属性名 | 类型 | 描述 | 默认值 | | ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ | | onClick | `(event: MouseEvent) => void \| boolean` | 点击事件,如果返回 false 可以阻塞重置 | - | | onResetValidateSuccess | (payload: any) => void | 重置校验成功事件 | - | -| onResetValidateFailed | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | 重置校验失败事件 | - | +| onResetValidateFailed | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | 重置校验失败事件 | diff --git a/docs/components/Select.md b/docs/components/Select.md index a8fe252..815babf 100644 --- a/docs/components/Select.md +++ b/docs/components/Select.md @@ -4,315 +4,19 @@ ## Markup Schema synchronization data source case -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - Submit - - -) -``` + ## Markup Schema Asynchronous Search Case -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { - createForm, - onFieldReact, - onFieldInit, - FormPathPattern, - Field, -} from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action, observable } from '@formily/reactive' -import { fetch } from 'mfetch' - -let timeout -let currentValue - -function fetchData(value, callback) { - if (timeout) { - clearTimeout(timeout) - timeout = null - } - currentValue = value - - function fake() { - fetch(`https://suggest.taobao.com/sug?q=${value}`, { - method: 'jsonp', - }) - .then((response) => response.json()) - .then((d) => { - if (currentValue === value) { - const { result } = d - const data = [] - result.forEach((r) => { - data.push({ - value: r[0], - text: r[0], - }) - }) - callback(data) - } - }) - } - - timeout = setTimeout(fake, 300) -} - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: Field) => Promise<{ label: string; value: any }[]> -) => { - const keyword = observable.ref('') - - onFieldInit(pattern, (field) => { - field.setComponentProps({ - onSearch: (value) => { - keyword.value = value - }, - }) - }) - - onFieldReact(pattern, (field) => { - field.loading = true - service({ field, keyword: keyword.value }).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async ({ keyword }) => { - if (!keyword) { - return [] - } - return new Promise((resolve) => { - fetchData(keyword, resolve) - }) - }) - }, -}) - -export default () => ( - - - - - - Submit - - -) -``` + ## Markup Schema Asynchronous Linkage Data Source Case -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: Field) => Promise<{ label: string; value: any }[]> -) => { - onFieldReact(pattern, (field) => { - field.loading = true - service(field).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) - }) - }, -}) - -export default () => ( - - - - - - - Submit - - -) -``` + ## JSON Schema synchronization data source case -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - select: { - type: 'string', - title: 'Select box', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - enum: [ - { label: 'Option 1', value: 1 }, - { label: 'Option 2', value: 2 }, - ], - 'x-component-props': { - style: { - width: 120, - }, - }, - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## JSON Schema asynchronous linkage data source case @@ -417,146 +121,16 @@ export default () => ( ) ``` -## Pure JSX synchronization data source case - -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' + -const form = createForm() +## Pure JSX synchronization data source case -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX asynchronous linkage data source case -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { - createForm, - onFieldReact, - FormPathPattern, - Field as FieldType, -} from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { action } from '@formily/reactive' - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: FieldType) => Promise<{ label: string; value: any }[]> -) => { - onFieldReact(pattern, (field) => { - field.loading = true - service(field).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) - }) - }, -}) - -export default () => ( - - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/select-cn/ +Reference diff --git a/docs/components/Select.zh-CN.md b/docs/components/Select.zh-CN.md index f0c146c..ba5218d 100644 --- a/docs/components/Select.zh-CN.md +++ b/docs/components/Select.zh-CN.md @@ -4,559 +4,32 @@ ## Markup Schema 同步数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - 提交 - - -) -``` + ## Markup Schema 异步搜索案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { - createForm, - onFieldReact, - onFieldInit, - FormPathPattern, - Field, -} from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action, observable } from '@formily/reactive' -import { fetch } from 'mfetch' - -let timeout -let currentValue - -function fetchData(value, callback) { - if (timeout) { - clearTimeout(timeout) - timeout = null - } - currentValue = value - - function fake() { - fetch(`https://suggest.taobao.com/sug?q=${value}`, { - method: 'jsonp', - }) - .then((response) => response.json()) - .then((d) => { - if (currentValue === value) { - const { result } = d - const data = [] - result.forEach((r) => { - data.push({ - value: r[0], - text: r[0], - }) - }) - callback(data) - } - }) - } - - timeout = setTimeout(fake, 300) -} - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: Field) => Promise<{ label: string; value: any }[]> -) => { - const keyword = observable.ref('') - - onFieldInit(pattern, (field) => { - field.setComponentProps({ - onSearch: (value) => { - keyword.value = value - }, - }) - }) - - onFieldReact(pattern, (field) => { - field.loading = true - service({ field, keyword: keyword.value }).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async ({ keyword }) => { - if (!keyword) { - return [] - } - return new Promise((resolve) => { - fetchData(keyword, resolve) - }) - }) - }, -}) - -export default () => ( - - - - - - 提交 - - -) -``` + ## Markup Schema 异步联动数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: Field) => Promise<{ label: string; value: any }[]> -) => { - onFieldReact(pattern, (field) => { - field.loading = true - service(field).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) - }) - }, -}) - -export default () => ( - - - - - - - 提交 - - -) -``` + ## JSON Schema 同步数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - select: { - type: 'string', - title: '选择框', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - enum: [ - { label: '选项1', value: 1 }, - { label: '选项2', value: 2 }, - ], - 'x-component-props': { - style: { - width: 120, - }, - }, - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## JSON Schema 异步联动数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { action } from '@formily/reactive' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const loadData = async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) -} - -const useAsyncDataSource = (service) => (field) => { - field.loading = true - service(field).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) -} - -const form = createForm() - -const schema = { - type: 'object', - properties: { - linkage: { - type: 'string', - title: '联动选择框', - enum: [ - { label: '发请求1', value: 1 }, - { label: '发请求2', value: 2 }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Select', - 'x-component-props': { - style: { - width: 120, - }, - }, - }, - select: { - type: 'string', - title: '异步选择框', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - 'x-component-props': { - style: { - width: 120, - }, - }, - 'x-reactions': ['{{useAsyncDataSource(loadData)}}'], - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 同步数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 异步联动数据源案例 -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { - createForm, - onFieldReact, - FormPathPattern, - Field as FieldType, -} from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { action } from '@formily/reactive' - -const useAsyncDataSource = ( - pattern: FormPathPattern, - service: (field: FieldType) => Promise<{ label: string; value: any }[]> -) => { - onFieldReact(pattern, (field) => { - field.loading = true - service(field).then( - action.bound((data) => { - field.dataSource = data - field.loading = false - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) - }) - }, -}) - -export default () => ( - - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/select-cn/ +参考 diff --git a/docs/components/SelectTable.md b/docs/components/SelectTable.md index f68c6b9..ab75c21 100644 --- a/docs/components/SelectTable.md +++ b/docs/components/SelectTable.md @@ -281,9 +281,6 @@ export default () => { name="selectTable3" x-decorator="FormItem" x-component="SelectTable" - x-component-props={{ - hasBorder: false, - }} default={['1', '3']} enum={[ { key: '1', name: 'title-1', description: 'description-1' }, @@ -597,9 +594,45 @@ export default () => ( ) ``` +## Pure JSX case + +```tsx +import React from 'react' +import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() + +export default () => ( + + + + Submit + + +) +``` + ## API -### SelectTable +### SelectTable API | Property name | Type | Description | Default value | | ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | @@ -613,7 +646,7 @@ export default () => ( | filterSort | (optionA, optionB) => number | Sort function for search options sorting, see Array.sort's compareFunction | - | | onSearch | Callback function that is fired when input changed | (inputValue) => void | - | -`TableProps` type definition reference antd https://ant.design/components/table/ +`TableProps` type definition reference antd ### rowSelection @@ -621,8 +654,8 @@ export default () => ( | ------------- | ------- | -------------------------------------------------------------------------- | ------------- | | checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true | -`rowSelectionProps` type definition reference antd https://ant.design/components/table/#rowSelection +`rowSelectionProps` type definition reference antd ### SelectTable.Column -`ColumnProps` type definition reference antd https://ant.design/components/table/ Table.Column +`ColumnProps` type definition reference antd Table.Column diff --git a/docs/components/SelectTable.zh-CN.md b/docs/components/SelectTable.zh-CN.md index 15ba288..a30e6b6 100644 --- a/docs/components/SelectTable.zh-CN.md +++ b/docs/components/SelectTable.zh-CN.md @@ -281,9 +281,6 @@ export default () => { name="selectTable3" x-decorator="FormItem" x-component="SelectTable" - x-component-props={{ - hasBorder: false, - }} default={['1', '3']} enum={[ { key: '1', name: '标题1', description: '描述1' }, @@ -593,9 +590,45 @@ export default () => ( ) ``` +## 纯 JSX 案例 + +```tsx +import React from 'react' +import { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() + +export default () => ( + + + + 提交 + + +) +``` + ## API -### SelectTable +### SelectTable API | 属性名 | 类型 | 描述 | 默认值 | | ------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------ | @@ -609,7 +642,7 @@ export default () => ( | filterSort | (optionA, optionB) => number | 搜索时对筛选结果项的排序函数, 类似 Array.sort 里的 compareFunction | - | | onSearch | 文本框值变化时回调 | (inputValue) => void | - | -参考 https://ant.design/components/table-cn/ +参考 ### rowSelection @@ -617,8 +650,8 @@ export default () => ( | ------------- | ------- | ------------------------------------------------------------ | ------ | | checkStrictly | boolean | checkable 状态下节点选择完全受控(父子数据选中状态不再关联) | true | -参考 https://ant.design/components/table/#rowSelection +参考 ### SelectTable.Column -参考 https://ant.design/components/table-cn/ Table.Column 属性 +参考 Table.Column 属性 diff --git a/docs/components/Space.md b/docs/components/Space.md index 9b1d9d3..3e21bbd 100644 --- a/docs/components/Space.md +++ b/docs/components/Space.md @@ -4,345 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - Space, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - - - Submit - - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - Space, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - name: { - type: 'void', - title: 'Name', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - asterisk: true, - feedbackLayout: 'none', - }, - 'x-component': 'Space', - properties: { - firstName: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - required: true, - }, - lastName: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - required: true, - }, - }, - }, - texts: { - type: 'void', - title: 'Text concatenation', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - asterisk: true, - feedbackLayout: 'none', - }, - 'x-component': 'Space', - properties: { - aa: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: 'Unit', - }, - 'x-component': 'Input', - required: true, - }, - bb: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: 'Unit', - }, - 'x-component': 'Input', - required: true, - }, - cc: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: 'Unit', - }, - 'x-component': 'Input', - required: true, - }, - }, - }, - - textarea: { - type: 'string', - title: 'Text box', - 'x-decorator': 'FormItem', - 'x-component': 'Input.TextArea', - 'x-component-props': { - style: { - width: 400, - }, - }, - required: true, - }, - }, -} - -export default () => ( - - - - - Submit - - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field, VoidField } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - Submit - - - -) -``` + ## API -Reference https://ant.design/components/space-cn/ +Reference diff --git a/docs/components/Space.zh-CN.md b/docs/components/Space.zh-CN.md index 34013f7..ffb3156 100644 --- a/docs/components/Space.zh-CN.md +++ b/docs/components/Space.zh-CN.md @@ -4,345 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - Space, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - - - 提交 - - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - Space, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - name: { - type: 'void', - title: '姓名', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - asterisk: true, - feedbackLayout: 'none', - }, - 'x-component': 'Space', - properties: { - firstName: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - required: true, - }, - lastName: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - required: true, - }, - }, - }, - texts: { - type: 'void', - title: '文本串联', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - asterisk: true, - feedbackLayout: 'none', - }, - 'x-component': 'Space', - properties: { - aa: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: '单位', - }, - 'x-component': 'Input', - required: true, - }, - bb: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: '单位', - }, - 'x-component': 'Input', - required: true, - }, - cc: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-decorator-props': { - addonAfter: '单位', - }, - 'x-component': 'Input', - required: true, - }, - }, - }, - - textarea: { - type: 'string', - title: '文本框', - 'x-decorator': 'FormItem', - 'x-component': 'Input.TextArea', - 'x-component-props': { - style: { - width: 400, - }, - }, - required: true, - }, - }, -} - -export default () => ( - - - - - 提交 - - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { - Input, - FormItem, - FormLayout, - FormButtonGroup, - Submit, - Space, -} from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field, VoidField } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - - - - - - - - - - 提交 - - - -) -``` + ## API -参考 https://ant.design/components/space-cn/ +参考 diff --git a/docs/components/Submit.md b/docs/components/Submit.md index 7e0bf61..b594490 100644 --- a/docs/components/Submit.md +++ b/docs/components/Submit.md @@ -4,105 +4,15 @@ ## Ordinary submission -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Submit - - -) -``` + ## Prevent Duplicate Submission (Loading) -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - { - return new Promise((resolve) => { - setTimeout(() => { - console.log(values) - resolve() - }, 2000) - }) - }} - onSubmitFailed={console.log} - > - submit - - - -) -``` + ## API -For button-related API properties, we can refer to https://ant.design/components/button-cn/, and the rest are the unique API properties of the Submit component +For button-related API properties, we can refer to , and the rest are the unique API properties of the Submit component | Property name | Type | Description | Default value | | --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ------------- | diff --git a/docs/components/Submit.zh-CN.md b/docs/components/Submit.zh-CN.md index 6bcb30b..f1abf31 100644 --- a/docs/components/Submit.zh-CN.md +++ b/docs/components/Submit.zh-CN.md @@ -4,105 +4,15 @@ ## 普通提交 -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 提交 - - -) -``` + ## 防重复提交(Loading) -```tsx -import React from 'react' -import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Input, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - { - return new Promise((resolve) => { - setTimeout(() => { - console.log(values) - resolve() - }, 2000) - }) - }} - onSubmitFailed={console.log} - > - 提交 - - - -) -``` + ## API -按钮相关的 API 属性,我们参考 https://ant.design/components/button-cn/ 即可,剩下是 Submit 组件独有的 API 属性 +按钮相关的 API 属性,我们参考 即可,剩下是 Submit 组件独有的 API 属性 | 属性名 | 类型 | 描述 | 默认值 | | --------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ | diff --git a/docs/components/Switch.md b/docs/components/Switch.md index f00e22c..1eff516 100644 --- a/docs/components/Switch.md +++ b/docs/components/Switch.md @@ -4,102 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Switch, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Switch, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - switch: { - type: 'boolean', - title: 'Switch', - 'x-decorator': 'FormItem', - 'x-component': 'Switch', - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/switch-cn/ +Reference diff --git a/docs/components/Switch.zh-CN.md b/docs/components/Switch.zh-CN.md index 0d4cf8f..350d2f0 100644 --- a/docs/components/Switch.zh-CN.md +++ b/docs/components/Switch.zh-CN.md @@ -4,102 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Switch, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Switch, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - switch: { - type: 'boolean', - title: '开关', - 'x-decorator': 'FormItem', - 'x-component': 'Switch', - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/switch-cn/ +参考 diff --git a/docs/components/TimePicker.md b/docs/components/TimePicker.md index 788ec0a..c11d625 100644 --- a/docs/components/TimePicker.md +++ b/docs/components/TimePicker.md @@ -4,121 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - TimePicker, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - TimePicker, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - time: { - title: 'Time', - 'x-decorator': 'FormItem', - 'x-component': 'TimePicker', - type: 'string', - }, - '[startTime,endTime]': { - title: 'Time Range', - 'x-decorator': 'FormItem', - 'x-component': 'TimePicker.RangePicker', - type: 'string', - }, - }, -} - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - Submit - - -) -``` + ## API -Reference https://ant.design/components/time-picker-cn/ +Reference diff --git a/docs/components/TimePicker.zh-CN.md b/docs/components/TimePicker.zh-CN.md index a12602c..267a4d1 100644 --- a/docs/components/TimePicker.zh-CN.md +++ b/docs/components/TimePicker.zh-CN.md @@ -4,121 +4,16 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - TimePicker, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - - - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - TimePicker, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - time: { - title: '时间', - 'x-decorator': 'FormItem', - 'x-component': 'TimePicker', - type: 'string', - }, - '[startTime,endTime]': { - title: '时间范围', - 'x-decorator': 'FormItem', - 'x-component': 'TimePicker.RangePicker', - type: 'string', - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - - 提交 - - -) -``` + ## API -参考 https://ant.design/components/time-picker-cn/ +参考 diff --git a/docs/components/Transfer.md b/docs/components/Transfer.md index 2f90799..2c29d7c 100644 --- a/docs/components/Transfer.md +++ b/docs/components/Transfer.md @@ -4,127 +4,16 @@ ## Markup Schema example -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Transfer, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - item.title, - }} - /> - - - Submit - - -) -``` + ## JSON Schema case -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Transfer, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - transfer: { - type: 'array', - title: 'shuttle box', - 'x-decorator': 'FormItem', - 'x-component': 'Transfer', - enum: [ - { title: 'Option 1', key: 1 }, - { title: 'Option 2', key: 2 }, - ], - 'x-component-props': { - render: '{{renderTitle}}', - }, - }, - }, -} - -const renderTitle = (item) => item.title - -export default () => ( - - - - Submit - - -) -``` + ## Pure JSX case -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - item.title, - }, - ]} - /> - - Submit - - -) -``` + ## API -Reference https://ant.design/components/transfer-cn/ +Reference diff --git a/docs/components/Transfer.zh-CN.md b/docs/components/Transfer.zh-CN.md index 7e124c3..e4c730f 100644 --- a/docs/components/Transfer.zh-CN.md +++ b/docs/components/Transfer.zh-CN.md @@ -4,127 +4,15 @@ ## Markup Schema 案例 -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Transfer, - FormItem, - }, -}) - -const form = createForm() - -export default () => ( - - - item.title, - }} - /> - - - 提交 - - -) -``` + ## JSON Schema 案例 -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Transfer, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - transfer: { - type: 'array', - title: '穿梭框', - 'x-decorator': 'FormItem', - 'x-component': 'Transfer', - enum: [ - { title: '选项1', key: 1 }, - { title: '选项2', key: 2 }, - ], - 'x-component-props': { - render: '{{renderTitle}}', - }, - }, - }, -} - -const renderTitle = (item) => item.title - -export default () => ( - - - - 提交 - - -) -``` + ## 纯 JSX 案例 -```tsx -import React from 'react' -import { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - item.title, - }, - ]} - /> - - 提交 - - -) -``` - + ## API -参考 https://ant.design/components/transfer-cn/ +参考 diff --git a/docs/components/TreeSelect.md b/docs/components/TreeSelect.md index 9e2512e..0932b3b 100644 --- a/docs/components/TreeSelect.md +++ b/docs/components/TreeSelect.md @@ -779,4 +779,4 @@ export default () => ( ## API -Reference https://ant.design/components/tree-select-cn/ +Reference diff --git a/docs/components/TreeSelect.zh-CN.md b/docs/components/TreeSelect.zh-CN.md index fc61a22..511e671 100644 --- a/docs/components/TreeSelect.zh-CN.md +++ b/docs/components/TreeSelect.zh-CN.md @@ -779,4 +779,4 @@ export default () => ( ## API -参考 https://ant.design/components/tree-select-cn/ +参考 diff --git a/docs/components/Upload.md b/docs/components/Upload.md index 33505e8..1ae17c9 100644 --- a/docs/components/Upload.md +++ b/docs/components/Upload.md @@ -330,4 +330,4 @@ export default () => ( ## API -Reference https://ant.design/components/upload-cn/ +Reference diff --git a/docs/components/Upload.zh-CN.md b/docs/components/Upload.zh-CN.md index 9428dce..20541c5 100644 --- a/docs/components/Upload.zh-CN.md +++ b/docs/components/Upload.zh-CN.md @@ -330,4 +330,4 @@ export default () => ( ## API -参考 https://ant.design/components/upload-cn/ +参考 diff --git a/docs/components/index.md b/docs/components/index.md index 1215824..e5733ee 100644 --- a/docs/components/index.md +++ b/docs/components/index.md @@ -2,7 +2,7 @@ ## Introduction -@formily/antd is a professional component library for form scenarios based on Ant Design encapsulation. It has the following characteristics: +@formily/antd 3.0 is a professional component library for form scenarios based on Ant Design V5 encapsulation. It has the following characteristics: - Only Formily 2.x is supported - Most components are not backward compatible @@ -60,8 +60,8 @@ ## Installation ```bash -$ npm install --save antd moment -$ npm install --save @formily/core @formily/react @formily/antd +npm install --save antd moment +npm install --save @formily/core @formily/react @formily/antd ``` diff --git a/docs/components/index.zh-CN.md b/docs/components/index.zh-CN.md index e3b23fd..d7a2d70 100644 --- a/docs/components/index.zh-CN.md +++ b/docs/components/index.zh-CN.md @@ -2,7 +2,7 @@ ## 介绍 -@formily/antd 是基于 Ant Design 封装的针对表单场景专业级(Professional)组件库,它主要有以下几个特点: +@formily/antd 3.0 是基于 Ant Design V5 封装的针对表单场景专业级(Professional)组件库,它主要有以下几个特点: - 仅支持 Formily2.x - 大部分组件无法向后兼容 @@ -60,8 +60,8 @@ ## 安装 ```bash -$ npm install --save antd moment -$ npm install --save @formily/core @formily/react @formily/antd +npm install --save antd moment +npm install --save @formily/core @formily/react @formily/antd ``` diff --git a/docs/demos/cascader/Markup.tsx b/docs/demos/cascader/Markup.tsx new file mode 100644 index 0000000..6419e90 --- /dev/null +++ b/docs/demos/cascader/Markup.tsx @@ -0,0 +1,91 @@ +import { Cascader, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { + createForm, + Field, + FieldDataSource, + FormPathPattern, + onFieldReact, +} from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import { action } from '@formily/reactive' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Cascader, + }, +}) + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: Field) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo: React.FC = () => { + return ( + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/cascader/Markup.zh-CN.tsx b/docs/demos/cascader/Markup.zh-CN.tsx new file mode 100644 index 0000000..93af698 --- /dev/null +++ b/docs/demos/cascader/Markup.zh-CN.tsx @@ -0,0 +1,91 @@ +import { Cascader, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { + createForm, + Field, + FieldDataSource, + FormPathPattern, + onFieldReact, +} from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import { action } from '@formily/reactive' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Cascader, + }, +}) + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: Field) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo: React.FC = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/cascader/PureJsx.tsx b/docs/demos/cascader/PureJsx.tsx new file mode 100644 index 0000000..95dc7e1 --- /dev/null +++ b/docs/demos/cascader/PureJsx.tsx @@ -0,0 +1,84 @@ +import React from 'react' +import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { + createForm, + onFieldReact, + FormPathPattern, + FieldDataSource, + Field as FieldType, +} from '@formily/core' +import { FormProvider, Field } from '@formily/react' +import { action } from '@formily/reactive' + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/cascader/PureJsx.zh-CN.tsx b/docs/demos/cascader/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..02b19e8 --- /dev/null +++ b/docs/demos/cascader/PureJsx.zh-CN.tsx @@ -0,0 +1,84 @@ +import { Cascader, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { + createForm, + Field as FieldType, + FieldDataSource, + FormPathPattern, + onFieldReact, +} from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import { action } from '@formily/reactive' +import React from 'react' + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/cascader/Schema.tsx b/docs/demos/cascader/Schema.tsx new file mode 100644 index 0000000..3368f4c --- /dev/null +++ b/docs/demos/cascader/Schema.tsx @@ -0,0 +1,91 @@ +import React from 'react' +import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm, FieldDataSource, Field } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' +import { action } from '@formily/reactive' + +const SchemaField = createSchemaField({ + components: { + Cascader, + FormItem, + }, +}) + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const transformAddress = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transformAddress(cities) + const _districts = transformAddress(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) +} + +const useAsyncDataSource = + (url: string, transform: (data: any) => any) => (field: Field) => { + field.loading = true + fetch(url) + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + } + +const form = createForm() + +const schema = { + type: 'object', + properties: { + address: { + type: 'string', + title: 'Address Selection', + 'x-decorator': 'FormItem', + 'x-component': 'Cascader', + 'x-component-props': { + style: { + width: 240, + }, + }, + 'x-reactions': [ + '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}', + ], + }, + }, +} + +const Demo = () => { + return ( + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/cascader/Schema.zh-CN.tsx b/docs/demos/cascader/Schema.zh-CN.tsx new file mode 100644 index 0000000..a49894f --- /dev/null +++ b/docs/demos/cascader/Schema.zh-CN.tsx @@ -0,0 +1,91 @@ +import React from 'react' +import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm, FieldDataSource, Field } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' +import { action } from '@formily/reactive' + +const SchemaField = createSchemaField({ + components: { + Cascader, + FormItem, + }, +}) + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const transformAddress = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transformAddress(cities) + const _districts = transformAddress(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) +} + +const useAsyncDataSource = + (url: string, transform: (data: any) => any) => (field: Field) => { + field.loading = true + fetch(url) + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + } + +const form = createForm() + +const schema = { + type: 'object', + properties: { + address: { + type: 'string', + title: '地址选择', + 'x-decorator': 'FormItem', + 'x-component': 'Cascader', + 'x-component-props': { + style: { + width: 240, + }, + }, + 'x-reactions': [ + '{{useAsyncDataSource("//unpkg.com/china-location/dist/location.json",transformAddress)}}', + ], + }, + }, +} + +const Demo = () => { + return ( + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/checkbox/Markup.tsx b/docs/demos/checkbox/Markup.tsx new file mode 100644 index 0000000..5c5db95 --- /dev/null +++ b/docs/demos/checkbox/Markup.tsx @@ -0,0 +1,48 @@ +import { Checkbox, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Checkbox, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/checkbox/Markup.zh-CN.tsx b/docs/demos/checkbox/Markup.zh-CN.tsx new file mode 100644 index 0000000..f374bd8 --- /dev/null +++ b/docs/demos/checkbox/Markup.zh-CN.tsx @@ -0,0 +1,48 @@ +import { Checkbox, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Checkbox, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/checkbox/PureJsx.tsx b/docs/demos/checkbox/PureJsx.tsx new file mode 100644 index 0000000..bb9b53d --- /dev/null +++ b/docs/demos/checkbox/PureJsx.tsx @@ -0,0 +1,93 @@ +import { Checkbox, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { + createForm, + Field as FieldType, + FieldDataSource, + FormPathPattern, + onFieldReact, +} from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import { action } from '@formily/reactive' +import React from 'react' + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo = () => { + return ( + + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/checkbox/PureJsx.zh-CN.tsx b/docs/demos/checkbox/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..fc87c8b --- /dev/null +++ b/docs/demos/checkbox/PureJsx.zh-CN.tsx @@ -0,0 +1,93 @@ +import { Checkbox, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { + createForm, + Field as FieldType, + FieldDataSource, + FormPathPattern, + onFieldReact, +} from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import { action } from '@formily/reactive' +import React from 'react' + +interface AddressInfo { + code: string + name: string + cities?: Record + districts?: Record +} + +const useAddress = (pattern: FormPathPattern) => { + const transform = (data: Record = {}) => { + return Object.entries(data).reduce((buf, [key, value]) => { + if (typeof value === 'string') + return buf.concat({ + label: value, + value: key, + }) + const { name, code, cities, districts } = value + const _cities = transform(cities) + const _districts = transform(districts) + return buf.concat({ + label: name, + value: code, + children: _cities.length + ? _cities + : _districts.length + ? _districts + : undefined, + }) + }, []) + } + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + fetch('//unpkg.com/china-location/dist/location.json') + .then((res) => res.json()) + .then( + action.bound?.((data) => { + field.dataSource = transform(data) + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAddress('address') + }, +}) + +const Demo = () => { + return ( + + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/checkbox/Schema.tsx b/docs/demos/checkbox/Schema.tsx new file mode 100644 index 0000000..92729b9 --- /dev/null +++ b/docs/demos/checkbox/Schema.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Checkbox, + FormItem, + }, +}) + +const form = createForm() + +const schema = { + type: 'object', + properties: { + single: { + type: 'boolean', + title: 'Are you sure', + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', + }, + multiple: { + type: 'array', + title: 'Check', + enum: [ + { + label: 'Option 1', + value: 1, + }, + { + label: 'Option 2', + value: 2, + }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox.Group', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/checkbox/Schema.zh-CN.tsx b/docs/demos/checkbox/Schema.zh-CN.tsx new file mode 100644 index 0000000..9655934 --- /dev/null +++ b/docs/demos/checkbox/Schema.zh-CN.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Checkbox, + FormItem, + }, +}) + +const form = createForm() + +const schema = { + type: 'object', + properties: { + single: { + type: 'boolean', + title: '是否确认', + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', + }, + multiple: { + type: 'array', + title: 'Check', + enum: [ + { + label: '选项1', + value: 1, + }, + { + label: '选项2', + value: 2, + }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox.Group', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/date-picker/Markup.tsx b/docs/demos/date-picker/Markup.tsx new file mode 100644 index 0000000..1c282be --- /dev/null +++ b/docs/demos/date-picker/Markup.tsx @@ -0,0 +1,114 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + DatePicker, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/date-picker/Markup.zh-CN.tsx b/docs/demos/date-picker/Markup.zh-CN.tsx new file mode 100644 index 0000000..b8c3251 --- /dev/null +++ b/docs/demos/date-picker/Markup.zh-CN.tsx @@ -0,0 +1,114 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/date-picker/PureJsx.tsx b/docs/demos/date-picker/PureJsx.tsx new file mode 100644 index 0000000..5862817 --- /dev/null +++ b/docs/demos/date-picker/PureJsx.tsx @@ -0,0 +1,105 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/date-picker/PureJsx.zh-CN.tsx b/docs/demos/date-picker/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..462acbc --- /dev/null +++ b/docs/demos/date-picker/PureJsx.zh-CN.tsx @@ -0,0 +1,105 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/date-picker/Schema.tsx b/docs/demos/date-picker/Schema.tsx new file mode 100644 index 0000000..ed0c436 --- /dev/null +++ b/docs/demos/date-picker/Schema.tsx @@ -0,0 +1,120 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + DatePicker, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + date: { + title: 'Normal date', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + type: 'string', + }, + week: { + title: 'Week Selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'week', + }, + type: 'string', + }, + month: { + title: 'Month Selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'month', + }, + type: 'string', + }, + quarter: { + title: 'Fiscal Year Selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'quarter', + }, + type: 'string', + }, + year: { + title: 'Year selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'year', + }, + type: 'string', + }, + '[startDate,endDate]': { + title: 'Date range', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + showTime: true, + }, + type: 'string', + }, + range_week: { + title: 'Week range selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'week', + }, + type: 'string', + }, + range_month: { + title: 'Month Range Selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'month', + }, + type: 'string', + }, + range_quarter: { + title: 'Financial year range selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'quarter', + }, + type: 'string', + }, + range_year: { + name: 'range_year', + title: 'Year range selection', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'year', + }, + type: 'string', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/date-picker/Schema.zh-CN.tsx b/docs/demos/date-picker/Schema.zh-CN.tsx new file mode 100644 index 0000000..466b501 --- /dev/null +++ b/docs/demos/date-picker/Schema.zh-CN.tsx @@ -0,0 +1,120 @@ +import { DatePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + date: { + title: '普通日期', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + type: 'string', + }, + week: { + title: '周选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'week', + }, + type: 'string', + }, + month: { + title: '月选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'month', + }, + type: 'string', + }, + quarter: { + title: '财年选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'quarter', + }, + type: 'string', + }, + year: { + title: '年选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + picker: 'year', + }, + type: 'string', + }, + '[startDate,endDate]': { + title: '日期范围', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + showTime: true, + }, + type: 'string', + }, + range_week: { + title: '周范围选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'week', + }, + type: 'string', + }, + range_month: { + title: '月范围选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'month', + }, + type: 'string', + }, + range_quarter: { + title: '财年范围选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'quarter', + }, + type: 'string', + }, + range_year: { + name: 'range_year', + title: '年范围选择', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + picker: 'year', + }, + type: 'string', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/editable/Markup.tsx b/docs/demos/editable/Markup.tsx new file mode 100644 index 0000000..7a46ada --- /dev/null +++ b/docs/demos/editable/Markup.tsx @@ -0,0 +1,89 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm, ObjectField } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + Editable, + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + { + field.title = field.query('.void.date2').get('value') || field.title + }} + > + + + + { + field.title = field.value?.date || field.title + }} + > + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/editable/Markup.zh-CN.tsx b/docs/demos/editable/Markup.zh-CN.tsx new file mode 100644 index 0000000..78d8759 --- /dev/null +++ b/docs/demos/editable/Markup.zh-CN.tsx @@ -0,0 +1,89 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm, ObjectField } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + Editable, + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + { + field.title = field.query('.void.date2').get('value') || field.title + }} + > + + + + { + field.title = field.value?.date || field.title + }} + > + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/editable/PureJsx.tsx b/docs/demos/editable/PureJsx.tsx new file mode 100644 index 0000000..90c10d1 --- /dev/null +++ b/docs/demos/editable/PureJsx.tsx @@ -0,0 +1,79 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider, ObjectField, VoidField } from '@formily/react' +import React from 'react' + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + { + field.title = field.query('.void.date2').get('value') || field.title + }} + component={[Editable.Popover]} + > + + + + { + field.title = field.value?.date || field.title + }} + component={[Editable.Popover]} + > + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/editable/PureJsx.zh-CN.tsx b/docs/demos/editable/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..a006c1b --- /dev/null +++ b/docs/demos/editable/PureJsx.zh-CN.tsx @@ -0,0 +1,79 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider, ObjectField, VoidField } from '@formily/react' +import React from 'react' + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + { + field.title = field.query('.void.date2').get('value') || field.title + }} + component={[Editable.Popover]} + > + + + + { + field.title = field.value?.date || field.title + }} + component={[Editable.Popover]} + > + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/editable/Schema.tsx b/docs/demos/editable/Schema.tsx new file mode 100644 index 0000000..620ef80 --- /dev/null +++ b/docs/demos/editable/Schema.tsx @@ -0,0 +1,95 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + Editable, + Input, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + date: { + type: 'string', + title: 'Date', + 'x-decorator': 'Editable', + 'x-component': 'DatePicker', + }, + input: { + type: 'string', + title: 'input box', + 'x-decorator': 'Editable', + 'x-component': 'Input', + }, + void: { + type: 'void', + title: 'Virtual Node Container', + 'x-component': 'Editable.Popover', + 'x-reactions': + "{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}", + properties: { + date2: { + type: 'string', + title: 'Date', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + }, + input2: { + type: 'string', + title: 'input box', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + iobject: { + type: 'object', + title: 'Object node container', + 'x-component': 'Editable.Popover', + 'x-reactions': + '{{(field) => field.title = field.value && field.value.date || field.title}}', + properties: { + date: { + type: 'string', + title: 'Date', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + }, + input: { + type: 'string', + title: 'input box', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/editable/Schema.zh-CN.tsx b/docs/demos/editable/Schema.zh-CN.tsx new file mode 100644 index 0000000..0ea333f --- /dev/null +++ b/docs/demos/editable/Schema.zh-CN.tsx @@ -0,0 +1,95 @@ +import { + DatePicker, + Editable, + FormButtonGroup, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + DatePicker, + Editable, + Input, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + date: { + type: 'string', + title: '日期', + 'x-decorator': 'Editable', + 'x-component': 'DatePicker', + }, + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'Editable', + 'x-component': 'Input', + }, + void: { + type: 'void', + title: '虚拟节点容器', + 'x-component': 'Editable.Popover', + 'x-reactions': + "{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}", + properties: { + date2: { + type: 'string', + title: '日期', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + }, + input2: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + iobject: { + type: 'object', + title: '对象节点容器', + 'x-component': 'Editable.Popover', + 'x-reactions': + '{{(field) => field.title = field.value && field.value.date || field.title}}', + properties: { + date: { + type: 'string', + title: '日期', + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + }, + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/form-grid/Markup.tsx b/docs/demos/form-grid/Markup.tsx new file mode 100644 index 0000000..765d0a6 --- /dev/null +++ b/docs/demos/form-grid/Markup.tsx @@ -0,0 +1,84 @@ +import { + FormButtonGroup, + FormGrid, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + FormGrid, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/form-grid/Markup.zh-CN.tsx b/docs/demos/form-grid/Markup.zh-CN.tsx new file mode 100644 index 0000000..788c413 --- /dev/null +++ b/docs/demos/form-grid/Markup.zh-CN.tsx @@ -0,0 +1,84 @@ +import { + FormButtonGroup, + FormGrid, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + FormGrid, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/form-grid/Native.tsx b/docs/demos/form-grid/Native.tsx new file mode 100644 index 0000000..cd4bf7a --- /dev/null +++ b/docs/demos/form-grid/Native.tsx @@ -0,0 +1,166 @@ +import { FormGrid } from '@formily/antd' +import React from 'react' + +const { GridColumn } = FormGrid +const Cell = ({ children }) => { + return ( +
+ {children} +
+ ) +} + +const Demo: React.FC = () => { + return ( + +

maxColumns 3 + minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxColumns 3

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

Null

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

minWidth 150 +maxColumns 3

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxWidth 120+minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxWidth 120 + gridSpan -1

+ + + 1 + + + 2 + + + 3 + + +
+ ) +} +export default Demo diff --git a/docs/demos/form-grid/Native.zh-CN.tsx b/docs/demos/form-grid/Native.zh-CN.tsx new file mode 100644 index 0000000..cd4bf7a --- /dev/null +++ b/docs/demos/form-grid/Native.zh-CN.tsx @@ -0,0 +1,166 @@ +import { FormGrid } from '@formily/antd' +import React from 'react' + +const { GridColumn } = FormGrid +const Cell = ({ children }) => { + return ( +
+ {children} +
+ ) +} + +const Demo: React.FC = () => { + return ( + +

maxColumns 3 + minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxColumns 3

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

Null

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

minWidth 150 +maxColumns 3

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxWidth 120+minColumns 2

+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + +

maxWidth 120 + gridSpan -1

+ + + 1 + + + 2 + + + 3 + + +
+ ) +} +export default Demo diff --git a/docs/demos/form-grid/QueryForm.tsx b/docs/demos/form-grid/QueryForm.tsx new file mode 100644 index 0000000..9d6c9a9 --- /dev/null +++ b/docs/demos/form-grid/QueryForm.tsx @@ -0,0 +1,186 @@ +import React, { useMemo, Fragment } from 'react' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, observer } from '@formily/react' +import { + Form, + Input, + Select, + DatePicker, + FormItem, + FormGrid, + Submit, + Reset, + FormButtonGroup, +} from '@formily/antd' + +const useCollapseGrid = (maxRows: number) => { + const grid = useMemo( + () => + FormGrid.createFormGrid({ + maxColumns: 4, + maxWidth: 240, + maxRows: maxRows, + shouldVisible: (node, grid) => { + if (node.index === grid.childSize - 1) return true + if (grid.maxRows === Infinity) return true + if (!node.shadowRow) return false + return node.shadowRow < maxRows + 1 + }, + }), + [] + ) + const expanded = grid.maxRows === Infinity + const realRows = grid.shadowRows + const computeRows = grid.fullnessLastColumn + ? grid.shadowRows - 1 + : grid.shadowRows + + const toggle = () => { + if (grid.maxRows === Infinity) { + grid.maxRows = maxRows + } else { + grid.maxRows = Infinity + } + } + const takeType = () => { + if (realRows < maxRows + 1) return 'incomplete-wrap' + if (computeRows > maxRows) return 'collapsible' + return 'complete-wrap' + } + return { + grid, + expanded, + toggle, + type: takeType(), + } +} + +const QueryForm: React.FC = observer((props) => { + const { grid, expanded, toggle, type } = useCollapseGrid(1) + + const renderActions = () => { + return ( + + Query + Reset + + ) + } + + const renderButtonGroup = () => { + if (type === 'incomplete-wrap') { + return ( + + {renderActions()} + + ) + } + if (type === 'collapsible') { + return ( + + + { + e.preventDefault() + toggle() + }} + > + {expanded ? 'Fold' : 'UnFold'} + + + {renderActions()} + + ) + } + return ( + + {renderActions()} + + ) + } + + return ( +
+ + {props.children} + + {renderButtonGroup()} + + +
+ ) +}) + +const SchemaField = createSchemaField({ + components: { + QueryForm, + Input, + Select, + DatePicker, + FormItem, + }, +}) + +const Demo = () => { + const form = useMemo(() => createForm(), []) + return ( + + + + + + + + + + + + + + + ) +} + +export default Demo diff --git a/docs/demos/form-grid/QueryForm.zh-CN.tsx b/docs/demos/form-grid/QueryForm.zh-CN.tsx new file mode 100644 index 0000000..1b413b1 --- /dev/null +++ b/docs/demos/form-grid/QueryForm.zh-CN.tsx @@ -0,0 +1,186 @@ +import React, { useMemo, Fragment } from 'react' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, observer } from '@formily/react' +import { + Form, + Input, + Select, + DatePicker, + FormItem, + FormGrid, + Submit, + Reset, + FormButtonGroup, +} from '@formily/antd' + +const useCollapseGrid = (maxRows: number) => { + const grid = useMemo( + () => + FormGrid.createFormGrid({ + maxColumns: 4, + maxWidth: 240, + maxRows: maxRows, + shouldVisible: (node, grid) => { + if (node.index === grid.childSize - 1) return true + if (grid.maxRows === Infinity) return true + if (!node.shadowRow) return false + return node.shadowRow < maxRows + 1 + }, + }), + [] + ) + const expanded = grid.maxRows === Infinity + const realRows = grid.shadowRows + const computeRows = grid.fullnessLastColumn + ? grid.shadowRows - 1 + : grid.shadowRows + + const toggle = () => { + if (grid.maxRows === Infinity) { + grid.maxRows = maxRows + } else { + grid.maxRows = Infinity + } + } + const takeType = () => { + if (realRows < maxRows + 1) return 'incomplete-wrap' + if (computeRows > maxRows) return 'collapsible' + return 'complete-wrap' + } + return { + grid, + expanded, + toggle, + type: takeType(), + } +} + +const QueryForm: React.FC = observer((props) => { + const { grid, expanded, toggle, type } = useCollapseGrid(1) + + const renderActions = () => { + return ( + + 查询 + 重置 + + ) + } + + const renderButtonGroup = () => { + if (type === 'incomplete-wrap') { + return ( + + {renderActions()} + + ) + } + if (type === 'collapsible') { + return ( + + + { + e.preventDefault() + toggle() + }} + > + {expanded ? 'Fold' : 'UnFold'} + + + {renderActions()} + + ) + } + return ( + + {renderActions()} + + ) + } + + return ( +
+ + {props.children} + + {renderButtonGroup()} + + +
+ ) +}) + +const SchemaField = createSchemaField({ + components: { + QueryForm, + Input, + Select, + DatePicker, + FormItem, + }, +}) + +const Demo = () => { + const form = useMemo(() => createForm(), []) + return ( + + + + + + + + + + + + + + + ) +} + +export default Demo diff --git a/docs/demos/form-grid/Schema.tsx b/docs/demos/form-grid/Schema.tsx new file mode 100644 index 0000000..eb0d64a --- /dev/null +++ b/docs/demos/form-grid/Schema.tsx @@ -0,0 +1,89 @@ +import { + FormButtonGroup, + FormGrid, + FormItem, + Input, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + FormGrid, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + grid: { + type: 'void', + 'x-component': 'FormGrid', + 'x-component-props': { + minColumns: [4, 6, 10], + }, + properties: { + aaa: { + type: 'string', + title: 'AAA', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + bbb: { + type: 'string', + title: 'BBB', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + ccc: { + type: 'string', + title: 'CCC', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + ddd: { + type: 'string', + title: 'DDD', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + eee: { + type: 'string', + title: 'EEE', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + fff: { + type: 'string', + title: 'FFF', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + ggg: { + type: 'string', + title: 'GGG', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, +} +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/form-grid/Schema.zh-CN.tsx b/docs/demos/form-grid/Schema.zh-CN.tsx new file mode 100644 index 0000000..a27d824 --- /dev/null +++ b/docs/demos/form-grid/Schema.zh-CN.tsx @@ -0,0 +1,56 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + 'x-component-props': { + style: { + width: 240, + }, + }, + }, + textarea: { + type: 'string', + title: '文本框', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': { + style: { + width: 400, + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/form/Form.tsx b/docs/demos/form/Form.tsx new file mode 100644 index 0000000..206508e --- /dev/null +++ b/docs/demos/form/Form.tsx @@ -0,0 +1,74 @@ +import React from 'react' +import { + Input, + Select, + Form, + FormItem, + FormGrid, + FormButtonGroup, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field } from '@formily/react' + +const form = createForm() +const Demo = () => { + return ( +
+ + + + + + + + Query + + +
+ ) +} + +export default Demo diff --git a/docs/demos/form/Form.zh-CN.tsx b/docs/demos/form/Form.zh-CN.tsx new file mode 100644 index 0000000..463b432 --- /dev/null +++ b/docs/demos/form/Form.zh-CN.tsx @@ -0,0 +1,74 @@ +import React from 'react' +import { + Input, + Select, + Form, + FormItem, + FormGrid, + FormButtonGroup, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field } from '@formily/react' + +const form = createForm() +const Demo = () => { + return ( +
+ + + + + + + + 查询 + + +
+ ) +} + +export default Demo diff --git a/docs/demos/input/Markup.tsx b/docs/demos/input/Markup.tsx new file mode 100644 index 0000000..b3a3a42 --- /dev/null +++ b/docs/demos/input/Markup.tsx @@ -0,0 +1,50 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/input/Markup.zh-CN.tsx b/docs/demos/input/Markup.zh-CN.tsx new file mode 100644 index 0000000..2e96808 --- /dev/null +++ b/docs/demos/input/Markup.zh-CN.tsx @@ -0,0 +1,50 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/input/PureJsx.tsx b/docs/demos/input/PureJsx.tsx new file mode 100644 index 0000000..50eca25 --- /dev/null +++ b/docs/demos/input/PureJsx.tsx @@ -0,0 +1,44 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/input/PureJsx.zh-CN.tsx b/docs/demos/input/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..3d7f77d --- /dev/null +++ b/docs/demos/input/PureJsx.zh-CN.tsx @@ -0,0 +1,44 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/input/Schema.tsx b/docs/demos/input/Schema.tsx new file mode 100644 index 0000000..a17157e --- /dev/null +++ b/docs/demos/input/Schema.tsx @@ -0,0 +1,56 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: 'input box', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + 'x-component-props': { + style: { + width: 240, + }, + }, + }, + textarea: { + type: 'string', + title: 'text box', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': { + style: { + width: 400, + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/input/Schema.zh-CN.tsx b/docs/demos/input/Schema.zh-CN.tsx new file mode 100644 index 0000000..a27d824 --- /dev/null +++ b/docs/demos/input/Schema.zh-CN.tsx @@ -0,0 +1,56 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + 'x-component-props': { + style: { + width: 240, + }, + }, + }, + textarea: { + type: 'string', + title: '文本框', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': { + style: { + width: 400, + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/number-picker/Markup.tsx b/docs/demos/number-picker/Markup.tsx new file mode 100644 index 0000000..42f95f4 --- /dev/null +++ b/docs/demos/number-picker/Markup.tsx @@ -0,0 +1,38 @@ +import { FormButtonGroup, FormItem, NumberPicker, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + NumberPicker, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/number-picker/Markup.zh-CN.tsx b/docs/demos/number-picker/Markup.zh-CN.tsx new file mode 100644 index 0000000..f824a1b --- /dev/null +++ b/docs/demos/number-picker/Markup.zh-CN.tsx @@ -0,0 +1,38 @@ +import { FormButtonGroup, FormItem, NumberPicker, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + NumberPicker, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/number-picker/PureJsx.tsx b/docs/demos/number-picker/PureJsx.tsx new file mode 100644 index 0000000..a293bcc --- /dev/null +++ b/docs/demos/number-picker/PureJsx.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/number-picker/PureJsx.zh-CN.tsx b/docs/demos/number-picker/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..71ad23e --- /dev/null +++ b/docs/demos/number-picker/PureJsx.zh-CN.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/number-picker/Schema.tsx b/docs/demos/number-picker/Schema.tsx new file mode 100644 index 0000000..3eeec00 --- /dev/null +++ b/docs/demos/number-picker/Schema.tsx @@ -0,0 +1,44 @@ +import { FormButtonGroup, FormItem, NumberPicker, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + NumberPicker, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: 'input box', + 'x-decorator': 'FormItem', + 'x-component': 'NumberPicker', + required: true, + 'x-component-props': { + style: { + width: 240, + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/number-picker/Schema.zh-CN.tsx b/docs/demos/number-picker/Schema.zh-CN.tsx new file mode 100644 index 0000000..3e23f36 --- /dev/null +++ b/docs/demos/number-picker/Schema.zh-CN.tsx @@ -0,0 +1,44 @@ +import { FormButtonGroup, FormItem, NumberPicker, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + NumberPicker, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'NumberPicker', + required: true, + 'x-component-props': { + style: { + width: 240, + }, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/password/Markup.tsx b/docs/demos/password/Markup.tsx new file mode 100644 index 0000000..f4daf6f --- /dev/null +++ b/docs/demos/password/Markup.tsx @@ -0,0 +1,44 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Password, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + + ) +} +export default Demo diff --git a/docs/demos/password/Markup.zh-CN.tsx b/docs/demos/password/Markup.zh-CN.tsx new file mode 100644 index 0000000..0ea0efc --- /dev/null +++ b/docs/demos/password/Markup.zh-CN.tsx @@ -0,0 +1,44 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Password, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 提交 + + + + ) +} +export default Demo diff --git a/docs/demos/password/PureJsx.tsx b/docs/demos/password/PureJsx.tsx new file mode 100644 index 0000000..88939c9 --- /dev/null +++ b/docs/demos/password/PureJsx.tsx @@ -0,0 +1,36 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + Submit + + + + ) +} +export default Demo diff --git a/docs/demos/password/PureJsx.zh-CN.tsx b/docs/demos/password/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..e346ab4 --- /dev/null +++ b/docs/demos/password/PureJsx.zh-CN.tsx @@ -0,0 +1,36 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + + ) +} +export default Demo diff --git a/docs/demos/password/Schema.tsx b/docs/demos/password/Schema.tsx new file mode 100644 index 0000000..c3dc835 --- /dev/null +++ b/docs/demos/password/Schema.tsx @@ -0,0 +1,49 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Password, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: 'input box', + 'x-decorator': 'FormItem', + 'x-component': 'Password', + 'x-component-props': { + checkStrength: true, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + + Submit + + + + ) +} + +export default Demo diff --git a/docs/demos/password/Schema.zh-CN.tsx b/docs/demos/password/Schema.zh-CN.tsx new file mode 100644 index 0000000..1fffabf --- /dev/null +++ b/docs/demos/password/Schema.zh-CN.tsx @@ -0,0 +1,49 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Password, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Password, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + input: { + type: 'string', + title: '输入框', + 'x-decorator': 'FormItem', + 'x-component': 'Password', + 'x-component-props': { + checkStrength: true, + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + + ) +} + +export default Demo diff --git a/docs/demos/radio/Markup.tsx b/docs/demos/radio/Markup.tsx new file mode 100644 index 0000000..3298780 --- /dev/null +++ b/docs/demos/radio/Markup.tsx @@ -0,0 +1,42 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Radio, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/radio/Markup.zh-CN.tsx b/docs/demos/radio/Markup.zh-CN.tsx new file mode 100644 index 0000000..55d50ce --- /dev/null +++ b/docs/demos/radio/Markup.zh-CN.tsx @@ -0,0 +1,42 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Radio, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/radio/PureJsx.tsx b/docs/demos/radio/PureJsx.tsx new file mode 100644 index 0000000..ff4c260 --- /dev/null +++ b/docs/demos/radio/PureJsx.tsx @@ -0,0 +1,32 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/radio/PureJsx.zh-CN.tsx b/docs/demos/radio/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..842fb39 --- /dev/null +++ b/docs/demos/radio/PureJsx.zh-CN.tsx @@ -0,0 +1,32 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/radio/Schema.tsx b/docs/demos/radio/Schema.tsx new file mode 100644 index 0000000..092134c --- /dev/null +++ b/docs/demos/radio/Schema.tsx @@ -0,0 +1,48 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Radio, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + radio: { + type: 'number', + title: 'Single selection', + enum: [ + { + label: 'Option 1', + value: 1, + }, + { + label: 'Option 2', + value: 2, + }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Radio.Group', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/radio/Schema.zh-CN.tsx b/docs/demos/radio/Schema.zh-CN.tsx new file mode 100644 index 0000000..9084dc0 --- /dev/null +++ b/docs/demos/radio/Schema.zh-CN.tsx @@ -0,0 +1,48 @@ +import { FormButtonGroup, FormItem, Radio, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Radio, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + radio: { + type: 'number', + title: '单选', + enum: [ + { + label: '选项1', + value: 1, + }, + { + label: '选项2', + value: 2, + }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Radio.Group', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/reset/ForceEmpty.tsx b/docs/demos/reset/ForceEmpty.tsx new file mode 100644 index 0000000..3235e09 --- /dev/null +++ b/docs/demos/reset/ForceEmpty.tsx @@ -0,0 +1,42 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Reset + + + ) +} + +export default Demo diff --git a/docs/demos/reset/ForceEmpty.zh-CN.tsx b/docs/demos/reset/ForceEmpty.zh-CN.tsx new file mode 100644 index 0000000..1b6e833 --- /dev/null +++ b/docs/demos/reset/ForceEmpty.zh-CN.tsx @@ -0,0 +1,42 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 重置 + + + ) +} + +export default Demo diff --git a/docs/demos/reset/ForceEmptyAndVerfy.tsx b/docs/demos/reset/ForceEmptyAndVerfy.tsx new file mode 100644 index 0000000..0fe36d0 --- /dev/null +++ b/docs/demos/reset/ForceEmptyAndVerfy.tsx @@ -0,0 +1,43 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +export const Demo: React.FC = () => { + return ( + + + + + + + + 重置 + + + + ) +} + +export default Demo diff --git a/docs/demos/reset/ForceEmptyAndVerfy.zh-CN.tsx b/docs/demos/reset/ForceEmptyAndVerfy.zh-CN.tsx new file mode 100644 index 0000000..f2c7938 --- /dev/null +++ b/docs/demos/reset/ForceEmptyAndVerfy.zh-CN.tsx @@ -0,0 +1,44 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +export const Demo: React.FC = () => { + return ( + + + + + + + + 重置 + + + + ) +} + +export default Demo diff --git a/docs/demos/reset/Normal.tsx b/docs/demos/reset/Normal.tsx new file mode 100644 index 0000000..43ec0d1 --- /dev/null +++ b/docs/demos/reset/Normal.tsx @@ -0,0 +1,41 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Reset + + + ) +} +export default Demo diff --git a/docs/demos/reset/Normal.zh-CN.tsx b/docs/demos/reset/Normal.zh-CN.tsx new file mode 100644 index 0000000..184044e --- /dev/null +++ b/docs/demos/reset/Normal.zh-CN.tsx @@ -0,0 +1,41 @@ +import { FormButtonGroup, FormItem, Input, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 重置 + + + ) +} +export default Demo diff --git a/docs/demos/reset/Verify.tsx b/docs/demos/reset/Verify.tsx new file mode 100644 index 0000000..c154d42 --- /dev/null +++ b/docs/demos/reset/Verify.tsx @@ -0,0 +1,42 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Reset + + + ) +} + +export default Demo diff --git a/docs/demos/reset/Verify.zh-CN.tsx b/docs/demos/reset/Verify.zh-CN.tsx new file mode 100644 index 0000000..f7455ff --- /dev/null +++ b/docs/demos/reset/Verify.zh-CN.tsx @@ -0,0 +1,42 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 重置 + + + ) +} + +export default Demo diff --git a/docs/demos/select/MarkupAsync.tsx b/docs/demos/select/MarkupAsync.tsx new file mode 100644 index 0000000..1782b65 --- /dev/null +++ b/docs/demos/select/MarkupAsync.tsx @@ -0,0 +1,120 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { + createForm, + Field, + FieldDataSource, + FormPathPattern, + onFieldInit, + onFieldReact, +} from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import { action, observable } from '@formily/reactive' +import { fetch } from 'mfetch' +import React from 'react' + +let timeout: NodeJS.Timeout | null = null +let currentValue: string + +function fetchData(value: string, callback: (data: FieldDataSource) => void) { + if (timeout) { + clearTimeout(timeout) + timeout = null + } + currentValue = value + + function fake() { + fetch(`https://suggest.taobao.com/sug?q=${value}`, { + method: 'jsonp', + }) + .then((response) => response.json()) + .then((d) => { + if (currentValue === value) { + const { result } = d + const data: FieldDataSource = [] + result.forEach((r: string[]) => { + data.push({ + value: r[0], + text: r[0], + }) + }) + callback(data) + } + }) + } + + timeout = setTimeout(fake, 300) +} + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (param: { + keyword: string + field: Field + }) => Promise +) => { + const keyword = observable.ref('') + + onFieldInit(pattern, (field) => { + field.setComponentProps({ + onSearch: (value: string) => { + keyword.value = value + }, + }) + }) + + onFieldReact(pattern, (field: Field) => { + field.loading = true + service({ field, keyword: keyword.value }).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async ({ keyword }) => { + if (!keyword) { + return [] + } + return new Promise((resolve) => { + fetchData(keyword, resolve) + }) + }) + }, +}) + +const Demo = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/select/MarkupAsync.zh-CN.tsx b/docs/demos/select/MarkupAsync.zh-CN.tsx new file mode 100644 index 0000000..f2ea550 --- /dev/null +++ b/docs/demos/select/MarkupAsync.zh-CN.tsx @@ -0,0 +1,120 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { + createForm, + Field, + FieldDataSource, + FormPathPattern, + onFieldInit, + onFieldReact, +} from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import { action, observable } from '@formily/reactive' +import { fetch } from 'mfetch' +import React from 'react' + +let timeout: NodeJS.Timeout | null = null +let currentValue: string + +function fetchData(value: string, callback: (data: FieldDataSource) => void) { + if (timeout) { + clearTimeout(timeout) + timeout = null + } + currentValue = value + + function fake() { + fetch(`https://suggest.taobao.com/sug?q=${value}`, { + method: 'jsonp', + }) + .then((response) => response.json()) + .then((d) => { + if (currentValue === value) { + const { result } = d + const data: FieldDataSource = [] + result.forEach((r: string[]) => { + data.push({ + value: r[0], + text: r[0], + }) + }) + callback(data) + } + }) + } + + timeout = setTimeout(fake, 300) +} + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (param: { + keyword: string + field: Field + }) => Promise +) => { + const keyword = observable.ref('') + + onFieldInit(pattern, (field) => { + field.setComponentProps({ + onSearch: (value: string) => { + keyword.value = value + }, + }) + }) + + onFieldReact(pattern, (field: Field) => { + field.loading = true + service({ field, keyword: keyword.value }).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async ({ keyword }) => { + if (!keyword) { + return [] + } + return new Promise((resolve) => { + fetchData(keyword, resolve) + }) + }) + }, +}) + +const Demo = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/select/MarkupAsyncLinkage.tsx b/docs/demos/select/MarkupAsyncLinkage.tsx new file mode 100644 index 0000000..48cafe8 --- /dev/null +++ b/docs/demos/select/MarkupAsyncLinkage.tsx @@ -0,0 +1,103 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' +import { action } from '@formily/reactive' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (field: Field) => Promise<{ label: string; value: any }[]> +) => { + onFieldReact(pattern, (field: Field) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async (field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) + }) + }, +}) + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/MarkupAsyncLinkage.zh-CN.tsx b/docs/demos/select/MarkupAsyncLinkage.zh-CN.tsx new file mode 100644 index 0000000..23c128e --- /dev/null +++ b/docs/demos/select/MarkupAsyncLinkage.zh-CN.tsx @@ -0,0 +1,103 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' +import { action } from '@formily/reactive' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (field: Field) => Promise<{ label: string; value: any }[]> +) => { + onFieldReact(pattern, (field: Field) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async (field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) + }) + }, +}) + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/MarkupSync.tsx b/docs/demos/select/MarkupSync.tsx new file mode 100644 index 0000000..d5a11df --- /dev/null +++ b/docs/demos/select/MarkupSync.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/select/MarkupSync.zh-CN.tsx b/docs/demos/select/MarkupSync.zh-CN.tsx new file mode 100644 index 0000000..50bf0f1 --- /dev/null +++ b/docs/demos/select/MarkupSync.zh-CN.tsx @@ -0,0 +1,44 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/select/PureJsxAsync.tsx b/docs/demos/select/PureJsxAsync.tsx new file mode 100644 index 0000000..214d922 --- /dev/null +++ b/docs/demos/select/PureJsxAsync.tsx @@ -0,0 +1,101 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { + createForm, + onFieldReact, + FormPathPattern, + Field as FieldType, + FieldDataSource, +} from '@formily/core' +import { FormProvider, Field } from '@formily/react' +import { action } from '@formily/reactive' + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (field: FieldType) => Promise +) => { + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async (field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) + }) + }, +}) + +const Demo = () => ( + + + + + 提交 + + +) +export default Demo diff --git a/docs/demos/select/PureJsxAsync.zh-CN.tsx b/docs/demos/select/PureJsxAsync.zh-CN.tsx new file mode 100644 index 0000000..85e78e4 --- /dev/null +++ b/docs/demos/select/PureJsxAsync.zh-CN.tsx @@ -0,0 +1,101 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { + createForm, + onFieldReact, + FormPathPattern, + Field as FieldType, + FieldDataSource, +} from '@formily/core' +import { FormProvider, Field } from '@formily/react' +import { action } from '@formily/reactive' + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (field: FieldType) => Promise +) => { + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async (field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) + }) + }, +}) + +const Demo = () => ( + + + + + 提交 + + +) +export default Demo diff --git a/docs/demos/select/PureJsxSync.tsx b/docs/demos/select/PureJsxSync.tsx new file mode 100644 index 0000000..59047eb --- /dev/null +++ b/docs/demos/select/PureJsxSync.tsx @@ -0,0 +1,35 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() + +const Demo = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/PureJsxSync.zh-CN.tsx b/docs/demos/select/PureJsxSync.zh-CN.tsx new file mode 100644 index 0000000..3d7f77d --- /dev/null +++ b/docs/demos/select/PureJsxSync.zh-CN.tsx @@ -0,0 +1,44 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, Field } from '@formily/react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/select/SchemaAsync.tsx b/docs/demos/select/SchemaAsync.tsx new file mode 100644 index 0000000..aa63034 --- /dev/null +++ b/docs/demos/select/SchemaAsync.tsx @@ -0,0 +1,103 @@ +import React from 'react' +import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { + createForm, + onFieldReact, + FormPathPattern, + Field as FieldType, +} from '@formily/core' +import { FormProvider, Field } from '@formily/react' +import { action } from '@formily/reactive' + +const useAsyncDataSource = ( + pattern: FormPathPattern, + service: (field: FieldType) => Promise<{ label: string; value: any }[]> +) => { + onFieldReact(pattern, (field: FieldType) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) + }) +} + +const form = createForm({ + effects: () => { + useAsyncDataSource('select', async (field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) + }) + }, +}) + +const Demo: React.FC = () => { + return ( + + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/SchemaAsync.zh-CN.tsx b/docs/demos/select/SchemaAsync.zh-CN.tsx new file mode 100644 index 0000000..9610ff6 --- /dev/null +++ b/docs/demos/select/SchemaAsync.zh-CN.tsx @@ -0,0 +1,102 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { createForm, Field, FieldDataSource } from '@formily/core' +import React from 'react' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import { action } from '@formily/reactive' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const loadData = async (field: Field) => { + const linkage = field.query('linkage').get('value') + if (!linkage) return [] + return new Promise((resolve) => { + setTimeout(() => { + if (linkage === 1) { + resolve([ + { + label: 'AAA', + value: 'aaa', + }, + { + label: 'BBB', + value: 'ccc', + }, + ]) + } else if (linkage === 2) { + resolve([ + { + label: 'CCC', + value: 'ccc', + }, + { + label: 'DDD', + value: 'ddd', + }, + ]) + } + }, 1500) + }) +} + +const useAsyncDataSource = (service: typeof loadData) => (field: Field) => { + field.loading = true + service(field).then( + action.bound?.((data) => { + field.dataSource = data + field.loading = false + }) + ) +} + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + linkage: { + type: 'string', + title: '联动选择框', + enum: [ + { label: '发请求1', value: 1 }, + { label: '发请求2', value: 2 }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Select', + 'x-component-props': { + style: { + width: 120, + }, + }, + }, + select: { + type: 'string', + title: '异步选择框', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + 'x-component-props': { + style: { + width: 120, + }, + }, + 'x-reactions': ['{{useAsyncDataSource(loadData)}}'], + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/SchemaSync.tsx b/docs/demos/select/SchemaSync.tsx new file mode 100644 index 0000000..7443691 --- /dev/null +++ b/docs/demos/select/SchemaSync.tsx @@ -0,0 +1,46 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + select: { + type: 'string', + title: 'Select box', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: [ + { label: 'Option 1', value: 1 }, + { label: 'Option 2', value: 2 }, + ], + 'x-component-props': { + style: { + width: 120, + }, + }, + }, + }, +} +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/select/SchemaSync.zh-CN.tsx b/docs/demos/select/SchemaSync.zh-CN.tsx new file mode 100644 index 0000000..5eca9ce --- /dev/null +++ b/docs/demos/select/SchemaSync.zh-CN.tsx @@ -0,0 +1,46 @@ +import { FormButtonGroup, FormItem, Select, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Select, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + select: { + type: 'string', + title: '选择框', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: [ + { label: '选项1', value: 1 }, + { label: '选项2', value: 2 }, + ], + 'x-component-props': { + style: { + width: 120, + }, + }, + }, + }, +} +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/space/Markup.tsx b/docs/demos/space/Markup.tsx new file mode 100644 index 0000000..9ab6843 --- /dev/null +++ b/docs/demos/space/Markup.tsx @@ -0,0 +1,103 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { Space, Input, FormItem }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + + + Submit + + + + ) +} +export default Demo diff --git a/docs/demos/space/Markup.zh-CN.tsx b/docs/demos/space/Markup.zh-CN.tsx new file mode 100644 index 0000000..4dc2d69 --- /dev/null +++ b/docs/demos/space/Markup.zh-CN.tsx @@ -0,0 +1,103 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { Space, Input, FormItem }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + + + Submit + + + + ) +} +export default Demo diff --git a/docs/demos/space/PureJsx.tsx b/docs/demos/space/PureJsx.tsx new file mode 100644 index 0000000..2ee9408 --- /dev/null +++ b/docs/demos/space/PureJsx.tsx @@ -0,0 +1,110 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider, VoidField } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + Submit + + + + ) +} +export default Demo diff --git a/docs/demos/space/PureJsx.zh-CN.tsx b/docs/demos/space/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..e83e5e2 --- /dev/null +++ b/docs/demos/space/PureJsx.zh-CN.tsx @@ -0,0 +1,110 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider, VoidField } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + + + + + + + + + + 提交 + + + + ) +} +export default Demo diff --git a/docs/demos/space/Schema.tsx b/docs/demos/space/Schema.tsx new file mode 100644 index 0000000..47f0781 --- /dev/null +++ b/docs/demos/space/Schema.tsx @@ -0,0 +1,118 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + FormLayout, + Space, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + name: { + type: 'void', + title: 'Name', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + asterisk: true, + feedbackLayout: 'none', + }, + 'x-component': 'Space', + properties: { + firstName: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + }, + lastName: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + }, + }, + }, + texts: { + type: 'void', + title: 'Text concatenation', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + asterisk: true, + feedbackLayout: 'none', + }, + 'x-component': 'Space', + properties: { + aa: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: 'Unit', + }, + 'x-component': 'Input', + required: true, + }, + bb: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: 'Unit', + }, + 'x-component': 'Input', + required: true, + }, + cc: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: 'Unit', + }, + 'x-component': 'Input', + required: true, + }, + }, + }, + + textarea: { + type: 'string', + title: 'Text box', + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': { + style: { + width: 400, + }, + }, + required: true, + }, + }, +} +const Demo: React.FC = () => { + return ( + + + + + Submit + + + + ) +} + +export default Demo diff --git a/docs/demos/space/Schema.zh-CN.tsx b/docs/demos/space/Schema.zh-CN.tsx new file mode 100644 index 0000000..9b89945 --- /dev/null +++ b/docs/demos/space/Schema.zh-CN.tsx @@ -0,0 +1,119 @@ +import { + FormButtonGroup, + FormItem, + FormLayout, + Input, + Space, + Submit, +} from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + FormLayout, + Space, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + name: { + type: 'void', + title: '姓名', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + asterisk: true, + feedbackLayout: 'none', + }, + 'x-component': 'Space', + properties: { + firstName: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + }, + lastName: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + required: true, + }, + }, + }, + texts: { + type: 'void', + title: '文本串联', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + asterisk: true, + feedbackLayout: 'none', + }, + 'x-component': 'Space', + properties: { + aa: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: '单位', + }, + 'x-component': 'Input', + required: true, + }, + bb: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: '单位', + }, + 'x-component': 'Input', + required: true, + }, + cc: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + addonAfter: '单位', + }, + 'x-component': 'Input', + required: true, + }, + }, + }, + + textarea: { + type: 'string', + title: '文本框', + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': { + style: { + width: 400, + }, + }, + required: true, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + + Submit + + + + ) +} + +export default Demo diff --git a/docs/demos/submit/Ordinary.tsx b/docs/demos/submit/Ordinary.tsx new file mode 100644 index 0000000..5e39651 --- /dev/null +++ b/docs/demos/submit/Ordinary.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/submit/Ordinary.zh-CN.tsx b/docs/demos/submit/Ordinary.zh-CN.tsx new file mode 100644 index 0000000..a1c7177 --- /dev/null +++ b/docs/demos/submit/Ordinary.zh-CN.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { FormProvider, createSchemaField } from '@formily/react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/submit/PreventDuplicate.tsx b/docs/demos/submit/PreventDuplicate.tsx new file mode 100644 index 0000000..13f6f0a --- /dev/null +++ b/docs/demos/submit/PreventDuplicate.tsx @@ -0,0 +1,54 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo = () => { + return ( + + + + + + + { + return new Promise((resolve) => { + setTimeout(() => { + console.log(values) + resolve() + }, 2000) + }) + }} + onSubmitFailed={console.log} + > + submit + + + + ) +} + +export default Demo diff --git a/docs/demos/submit/PreventDuplicate.zh-CN.tsx b/docs/demos/submit/PreventDuplicate.zh-CN.tsx new file mode 100644 index 0000000..f5a4f6e --- /dev/null +++ b/docs/demos/submit/PreventDuplicate.zh-CN.tsx @@ -0,0 +1,54 @@ +import { FormButtonGroup, FormItem, Input, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Input, + FormItem, + }, +}) + +const form = createForm() + +const Demo = () => { + return ( + + + + + + + { + return new Promise((resolve) => { + setTimeout(() => { + console.log(values) + resolve() + }, 2000) + }) + }} + onSubmitFailed={console.log} + > + 提交 + + + + ) +} + +export default Demo diff --git a/docs/demos/switch/Markup.tsx b/docs/demos/switch/Markup.tsx new file mode 100644 index 0000000..d9de4f6 --- /dev/null +++ b/docs/demos/switch/Markup.tsx @@ -0,0 +1,32 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Switch, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/switch/Markup.zh-CN.tsx b/docs/demos/switch/Markup.zh-CN.tsx new file mode 100644 index 0000000..00808d5 --- /dev/null +++ b/docs/demos/switch/Markup.zh-CN.tsx @@ -0,0 +1,32 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Switch, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/switch/PureJsx.tsx b/docs/demos/switch/PureJsx.tsx new file mode 100644 index 0000000..f457780 --- /dev/null +++ b/docs/demos/switch/PureJsx.tsx @@ -0,0 +1,22 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/switch/PureJsx.zh-CN.tsx b/docs/demos/switch/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..88a4370 --- /dev/null +++ b/docs/demos/switch/PureJsx.zh-CN.tsx @@ -0,0 +1,22 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/switch/Schema.tsx b/docs/demos/switch/Schema.tsx new file mode 100644 index 0000000..4694f22 --- /dev/null +++ b/docs/demos/switch/Schema.tsx @@ -0,0 +1,38 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Switch, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + switch: { + type: 'boolean', + title: 'Switch', + 'x-decorator': 'FormItem', + 'x-component': 'Switch', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/switch/Schema.zh-CN.tsx b/docs/demos/switch/Schema.zh-CN.tsx new file mode 100644 index 0000000..50612b0 --- /dev/null +++ b/docs/demos/switch/Schema.zh-CN.tsx @@ -0,0 +1,38 @@ +import { FormButtonGroup, FormItem, Submit, Switch } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Switch, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + switch: { + type: 'boolean', + title: '开关', + 'x-decorator': 'FormItem', + 'x-component': 'Switch', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/time-picker/Markup.tsx b/docs/demos/time-picker/Markup.tsx new file mode 100644 index 0000000..e0d0eec --- /dev/null +++ b/docs/demos/time-picker/Markup.tsx @@ -0,0 +1,39 @@ +import { TimePicker, FormButtonGroup, FormItem, Submit } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + TimePicker, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/time-picker/Markup.zh-CN.tsx b/docs/demos/time-picker/Markup.zh-CN.tsx new file mode 100644 index 0000000..4332d94 --- /dev/null +++ b/docs/demos/time-picker/Markup.zh-CN.tsx @@ -0,0 +1,39 @@ +import { FormButtonGroup, FormItem, Submit, TimePicker } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + TimePicker, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/time-picker/PureJsx.tsx b/docs/demos/time-picker/PureJsx.tsx new file mode 100644 index 0000000..8980f4e --- /dev/null +++ b/docs/demos/time-picker/PureJsx.tsx @@ -0,0 +1,28 @@ +import { FormButtonGroup, FormItem, Submit, TimePicker } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/time-picker/PureJsx.zh-CN.tsx b/docs/demos/time-picker/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..16853d6 --- /dev/null +++ b/docs/demos/time-picker/PureJsx.zh-CN.tsx @@ -0,0 +1,28 @@ +import { FormButtonGroup, FormItem, Submit, TimePicker } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/time-picker/Schema.tsx b/docs/demos/time-picker/Schema.tsx new file mode 100644 index 0000000..cf351e1 --- /dev/null +++ b/docs/demos/time-picker/Schema.tsx @@ -0,0 +1,43 @@ +import { FormButtonGroup, FormItem, Submit, TimePicker } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + TimePicker, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + time: { + title: 'Time', + 'x-decorator': 'FormItem', + 'x-component': 'TimePicker', + type: 'string', + }, + '[startTime,endTime]': { + title: 'Time Range', + 'x-decorator': 'FormItem', + 'x-component': 'TimePicker.RangePicker', + type: 'string', + }, + }, +} +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/time-picker/Schema.zh-CN.tsx b/docs/demos/time-picker/Schema.zh-CN.tsx new file mode 100644 index 0000000..9e5267d --- /dev/null +++ b/docs/demos/time-picker/Schema.zh-CN.tsx @@ -0,0 +1,44 @@ +import { FormButtonGroup, FormItem, Submit, TimePicker } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + TimePicker, + FormItem, + }, +}) + +const form = createForm() + +const schema: ISchema = { + type: 'object', + properties: { + time: { + title: '时间', + 'x-decorator': 'FormItem', + 'x-component': 'TimePicker', + type: 'string', + }, + '[startTime,endTime]': { + title: '时间范围', + 'x-decorator': 'FormItem', + 'x-component': 'TimePicker.RangePicker', + type: 'string', + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/demos/transfer/Markup.tsx b/docs/demos/transfer/Markup.tsx new file mode 100644 index 0000000..72a8c28 --- /dev/null +++ b/docs/demos/transfer/Markup.tsx @@ -0,0 +1,40 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Transfer, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + item.title ?? null, + }} + /> + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/transfer/Markup.zh-CN.tsx b/docs/demos/transfer/Markup.zh-CN.tsx new file mode 100644 index 0000000..a6e86e1 --- /dev/null +++ b/docs/demos/transfer/Markup.zh-CN.tsx @@ -0,0 +1,39 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider } from '@formily/react' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + Transfer, + FormItem, + }, +}) + +const form = createForm() + +const Demo: React.FC = () => { + return ( + + + item.title ?? null, + }} + /> + + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/transfer/PureJsx.tsx b/docs/demos/transfer/PureJsx.tsx new file mode 100644 index 0000000..741c3ea --- /dev/null +++ b/docs/demos/transfer/PureJsx.tsx @@ -0,0 +1,31 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + item.title, + }, + ]} + /> + + Submit + + + ) +} +export default Demo diff --git a/docs/demos/transfer/PureJsx.zh-CN.tsx b/docs/demos/transfer/PureJsx.zh-CN.tsx new file mode 100644 index 0000000..a1120a0 --- /dev/null +++ b/docs/demos/transfer/PureJsx.zh-CN.tsx @@ -0,0 +1,31 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { Field, FormProvider } from '@formily/react' +import React from 'react' + +const form = createForm() +const Demo: React.FC = () => { + return ( + + item.title, + }, + ]} + /> + + 提交 + + + ) +} +export default Demo diff --git a/docs/demos/transfer/Schema.tsx b/docs/demos/transfer/Schema.tsx new file mode 100644 index 0000000..b277e19 --- /dev/null +++ b/docs/demos/transfer/Schema.tsx @@ -0,0 +1,48 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import type { TransferItem } from 'antd/es/transfer' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Transfer, + }, +}) + +const form = createForm() + +const renderTitle = (item: TransferItem) => item.title + +const schema: ISchema = { + type: 'object', + properties: { + transfer: { + type: 'array', + title: 'shuttle box', + 'x-decorator': 'FormItem', + 'x-component': 'Transfer', + enum: [ + { title: 'Option 1', key: 1 }, + { title: 'Option 2', key: 2 }, + ], + 'x-component-props': { + render: '{{renderTitle}}', + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + Submit + + + ) +} + +export default Demo diff --git a/docs/demos/transfer/Schema.zh-CN.tsx b/docs/demos/transfer/Schema.zh-CN.tsx new file mode 100644 index 0000000..2984bf1 --- /dev/null +++ b/docs/demos/transfer/Schema.zh-CN.tsx @@ -0,0 +1,48 @@ +import { FormButtonGroup, FormItem, Submit, Transfer } from '@formily/antd' +import { createForm } from '@formily/core' +import { createSchemaField, FormProvider, ISchema } from '@formily/react' +import type { TransferItem } from 'antd/es/transfer' +import React from 'react' + +const SchemaField = createSchemaField({ + components: { + FormItem, + Transfer, + }, +}) + +const form = createForm() + +const renderTitle = (item: TransferItem) => item.title + +const schema: ISchema = { + type: 'object', + properties: { + transfer: { + type: 'array', + title: '穿梭框', + 'x-decorator': 'FormItem', + 'x-component': 'Transfer', + enum: [ + { title: '选项1', key: 1 }, + { title: '选项2', key: 2 }, + ], + 'x-component-props': { + render: '{{renderTitle}}', + }, + }, + }, +} + +const Demo: React.FC = () => { + return ( + + + + 提交 + + + ) +} + +export default Demo diff --git a/docs/index.md b/docs/index.md index 1a24854..26d3c8d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,64 +25,7 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## Installation ```bash -$ npm install --save antd moment -$ npm install --save @formily/core @formily/react @formily/antd +npm install --save antd moment +npm install --save @formily/core @formily/react @formily/antd ``` - -## Quick start - -```tsx -/** - * defaultShowCode: true - */ -import React from 'react' -import { NumberPicker, FormItem, Space } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, FormConsumer, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - × - - - {(form) => ( - ={` ${form.values.price * form.values.count}元`} - )} - - - -) -``` diff --git a/docs/index.zh-CN.md b/docs/index.zh-CN.md index 449e271..bcd2f8c 100644 --- a/docs/index.zh-CN.md +++ b/docs/index.zh-CN.md @@ -25,64 +25,9 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## 安装 ```bash -$ npm install --save antd moment -$ npm install --save @formily/core @formily/react @formily/antd +npm install --save antd moment +npm install --save @formily/core @formily/react @formily/antd ``` ## 快速开始 - -```tsx -/** - * defaultShowCode: true - */ -import React from 'react' -import { NumberPicker, FormItem, Space } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, FormConsumer, Field } from '@formily/react' - -const form = createForm() - -export default () => ( - - - - × - - - {(form) => ( - ={` ${form.values.price * form.values.count} 元`} - )} - - - -) -``` diff --git a/docs/types.ts b/docs/types.ts new file mode 100644 index 0000000..921da69 --- /dev/null +++ b/docs/types.ts @@ -0,0 +1,5 @@ +declare module 'mfetch' { + type Fetch = typeof fetch + const mfetch: Fetch + export { mfetch as fetch } +} diff --git a/global.config.d.ts b/global.config.d.ts deleted file mode 100644 index 336ce12..0000000 --- a/global.config.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {} diff --git a/global.config.js b/global.config.js deleted file mode 100644 index aacca1c..0000000 --- a/global.config.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' -var __importDefault = - (this && this.__importDefault) || - function (mod) { - return mod && mod.__esModule ? mod : { default: mod } - } -Object.defineProperty(exports, '__esModule', { value: true }) -var pretty_format_1 = __importDefault(require('pretty-format')) -global['prettyFormat'] = pretty_format_1.default -global['sleep'] = function (time) { - return new Promise(function (resolve) { - return setTimeout(resolve, time) - }) -} -global['requestAnimationFrame'] = function (fn) { - return setTimeout(fn) -} -global.document.documentElement.style['grid-column-gap'] = true -;(function () { - var spy = jest.spyOn(console, 'error') - beforeAll(function () { - spy.mockImplementation(function (message) { - console.log(message) - throw new Error(message) - }) - }) - afterAll(function () { - spy.mockRestore() - }) -})() -//# sourceMappingURL=global.config.js.map diff --git a/global.config.js.map b/global.config.js.map deleted file mode 100644 index 2a6921c..0000000 --- a/global.config.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"global.config.js","sourceRoot":"","sources":["global.config.ts"],"names":[],"mappings":";;;;;AAAA,gEAAwC;AAExC,MAAM,CAAC,cAAc,CAAC,GAAG,uBAAY,CAAA;AAErC,MAAM,CAAC,OAAO,CAAC,GAAG,UAAC,IAAI;IACrB,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAzB,CAAyB,CAAC,CAAA;AAC5D,CAAC,CAAA;AAED,MAAM,CAAC,uBAAuB,CAAC,GAAG,UAAC,EAAE,IAAK,OAAA,UAAU,CAAC,EAAE,CAAC,EAAd,CAAc,CAAA;AAExD,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAG9D;AAAA,CAAC;IACA,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACxC,SAAS,CAAC;QACR,GAAG,CAAC,kBAAkB,CAAC,UAAC,OAAO;YAC7B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACpB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC;QACP,GAAG,CAAC,WAAW,EAAE,CAAA;IACnB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,EAAE,CAAA","sourcesContent":["import prettyFormat from 'pretty-format'\n\nglobal['prettyFormat'] = prettyFormat\n\nglobal['sleep'] = (time) => {\n return new Promise((resolve) => setTimeout(resolve, time))\n}\n\nglobal['requestAnimationFrame'] = (fn) => setTimeout(fn)\n\nglobal.document.documentElement.style['grid-column-gap'] = true\n\n// 把 console.error 转换成 error,方便断言\n;(() => {\n const spy = jest.spyOn(console, 'error')\n beforeAll(() => {\n spy.mockImplementation((message) => {\n console.log(message)\n throw new Error(message)\n })\n })\n\n afterAll(() => {\n spy.mockRestore()\n })\n})()\n"]} \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index f90028c..a8afc54 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,3 @@ -const path = require('path') module.exports = { collectCoverage: true, verbose: true, diff --git a/package.json b/package.json index 8e7192d..ce36fc4 100644 --- a/package.json +++ b/package.json @@ -1,143 +1,94 @@ { "name": "root", "private": true, - "devEngines": { - "node": "8.x || 9.x || 10.x || 11.x" + "repository": { + "type": "git", + "url": "git+https://github.com/formilyjs/antd.git" }, "workspaces": [ "packages/*" ], "scripts": { - "start": "dumi dev", "build": "formily-tpl build", "build:docs": "dumi build", + "lint": "eslint .", + "release": "lerna publish from-package --yes", + "start": "dumi dev", "test": "jest --coverage", "test:prod": "jest --coverage --silent", - "preversion": "yarn install --ignore-engines && npm run build && npm run lint && npm run test", + "preversion": "yarn install --ignore-engines && npm run build && npm run lint", "version:alpha": "lerna version prerelease --preid alpha", "version:beta": "lerna version prerelease --preid beta", - "version:rc": "lerna version prerelease --preid rc", - "version:patch": "lerna version patch", + "version:major": "lerna version major", "version:minor": "lerna version minor", + "version:patch": "lerna version patch", "version:preminor": "lerna version preminor --preid beta", - "version:major": "lerna version major", - "release": "lerna publish from-package --yes", - "lint": "eslint ." + "version:rc": "lerna version prerelease --preid rc" + }, + "lint-staged": { + "*.{ts,tsx,js}": [ + "eslint --ext .ts,.tsx,.js", + "pretty-quick --staged", + "git add" + ], + "*.md": [ + "pretty-quick --staged", + "git add" + ] + }, + "config": { + "ghooks": { + "pre-commit": "lint-staged", + "commit-msg": "commitlint --edit" + } }, + "dependencies": {}, "devDependencies": { - "@formily/template": "^1.0.0-alpha.20", - "@rollup/plugin-commonjs": "^17.0.0", + "@commitlint/cli": "^17.3.0", + "@commitlint/config-conventional": "^17.3.0", + "@commitlint/prompt-cli": "^17.3.0", + "@formily/template": "^1.0.0-alpha.21", "@testing-library/jest-dom": "^5.0.0", - "@testing-library/react": "^11.2.3", - "@netlify/functions": "^0.7.2", - "@types/fs-extra": "^8.1.0", - "@types/hoist-non-react-statics": "^3.3.1", + "@types/fs-extra": "^9.0.13", "@types/jest": "^24.0.18", - "@types/node": "^12.6.8", - "@types/react": "^17.0.0", - "@types/react-dom": "^17.0.0", - "@typescript-eslint/eslint-plugin": "^4.9.1", - "@typescript-eslint/parser": "^4.8.2", - "@umijs/plugin-sass": "^1.1.1", - "antd": "^4.0.0", - "chalk": "^2.4.2", - "chokidar": "^2.1.2", - "axios": "^0.23.0", - "querystring": "^0.2.1", - "concurrently": "^4.1.0", - "conventional-commit-types": "^2.2.0", - "cool-path": "^1.0.6", - "cross-env": "^5.2.0", - "css-loader": "^5.0.0", - "cz-conventional-changelog": "^2.1.0", - "dumi": "^1.1.34", - "escape-string-regexp": "^4.0.0", - "eslint": "^7.14.0", - "eslint-config-prettier": "^7.0.0", + "@types/node": "^18.11.9", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@typescript-eslint/eslint-plugin": "^5.44.0", + "@typescript-eslint/parser": "^5.44.0", + "antd": "^5.0.0", + "cross-env": "^7.0.3", + "dumi": "^1.1.0", + "eslint": "^8.28.0", + "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.13.0", - "eslint-plugin-markdown": "^2.0.1", + "eslint-plugin-markdown": "^3.0.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.1.0", - "eslint-plugin-promise": "^4.0.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.14.2", "eslint-plugin-react-hooks": "^4.2.0", - "execa": "^5.0.0", - "file-loader": "^5.0.2", - "findup": "^0.1.5", - "fs-extra": "^7.0.1", + "fs-extra": "^10.1.0", "ghooks": "^2.0.4", - "glob": "^7.1.3", - "html-webpack-plugin": "^3.2.0", - "immutable": "^4.0.0-rc.12", - "istanbul-api": "^2.1.1", - "istanbul-lib-coverage": "^2.0.3", + "glob": "^8.0.3", "jest": "^26.0.0", "jest-codemods": "^0.19.1", "jest-dom": "^3.1.2", "jest-localstorage-mock": "^2.3.0", "jest-styled-components": "6.3.3", "jest-watch-lerna-packages": "^1.1.0", - "lerna": "^4.0.0", - "less": "^4.1.1", - "less-loader": "^5.0.0", - "less-plugin-npm-import": "^2.1.0", - "lint-staged": "^8.2.1", + "lerna": "^6.0.0", + "lint-staged": "^13.0.4", "mfetch": "^0.2.27", - "mobx": "^6.0.4", - "mobx-react-lite": "^3.1.6", - "onchange": "^5.2.0", - "opencollective": "^1.0.3", - "opencollective-postinstall": "^2.0.2", - "param-case": "^3.0.4", - "postcss": "^8.0.0", "prettier": "^2.2.1", - "pretty-format": "^24.0.0", + "pretty-format": "^29.3.1", "pretty-quick": "^3.1.0", - "@commitlint/cli": "^14.1.0", - "@commitlint/prompt-cli": "^14.1.0", - "@commitlint/config-conventional": "^14.1.0", - "raw-loader": "^4.0.0", - "react": "^17.0.1", - "react-dom": "^17.0.1", - "react-mde": "^11.5.0", - "react-test-renderer": "^16.11.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "rimraf": "^3.0.0", - "semver": "^7.3.5", - "semver-regex": "^3.1.3", - "showdown": "^1.9.1", "staged-git-files": "^1.1.2", - "string-similarity": "^4.0.4", - "style-loader": "^1.1.3", - "styled-components": "^5.0.0", - "ts-import-plugin": "1.6.1", - "ts-jest": "^27.1.0", - "ts-loader": "^7.0.4", - "ts-node": "^9.1.1", - "typescript": "^4.1.5", - "webpack": "^4.41.5", - "webpack-cli": "^3.3.10", - "webpack-dev-server": "^3.10.1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/formilyjs/antd.git" - }, - "config": { - "ghooks": { - "pre-commit": "lint-staged", - "commit-msg": "commitlint --edit" - } - }, - "lint-staged": { - "*.{ts,tsx,js}": [ - "eslint --ext .ts,.tsx,.js", - "pretty-quick --staged", - "git add" - ], - "*.md": [ - "pretty-quick --staged", - "git add" - ] - }, - "dependencies": {} + "ts-jest": "^26.0.0", + "ts-node": "^10.9.1", + "typescript": "^4.1.5" + } } diff --git a/packages/.eslintrc b/packages/.eslintrc index 7c5d7dc..80742b7 100644 --- a/packages/.eslintrc +++ b/packages/.eslintrc @@ -3,7 +3,7 @@ "extends": [ "plugin:react/recommended", "plugin:@typescript-eslint/recommended", - "prettier/@typescript-eslint" + "prettier" ], "env": { "node": true diff --git a/packages/components/package.json b/packages/components/package.json index b7f1d31..f27b554 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@formily/antd", - "version": "2.0.13", + "version": "3.0.0-alpha.0", "license": "MIT", "main": "lib", "types": "lib/index.d.ts", @@ -38,23 +38,24 @@ "peerDependencies": { "@types/react": ">=16.8.0 || >=17.0.0", "@types/react-dom": ">=16.8.0 || >=17.0.0", - "antd": "^4.0.0", + "antd": "^5.0.0", "react": ">=16.8.0 || >=17.0.0", "react-dom": ">=16.8.0", "react-is": ">=16.8.0 || >=17.0.0" }, "dependencies": { "@ant-design/icons": "^4.0.0", - "@formily/core": "2.0.13", - "@formily/grid": "2.0.13", - "@formily/json-schema": "2.0.13", - "@formily/react": "2.0.13", - "@formily/reactive": "2.0.13", - "@formily/reactive-react": "2.0.13", - "@formily/shared": "2.0.13", + "@dnd-kit/core": "^6.0.0", + "@dnd-kit/sortable": "^7.0.0", + "@formily/core": "^2.2.0", + "@formily/grid": "^2.2.0", + "@formily/json-schema": "^2.2.0", + "@formily/react": "^2.2.0", + "@formily/reactive": "^2.2.0", + "@formily/reactive-react": "^2.2.0", + "@formily/shared": "^2.2.0", "classnames": "^2.2.6", - "react-sortable-hoc": "^1.11.0", - "react-sticky-box": "^0.9.3" + "react-sticky-box": "^1.0.2" }, "devDependencies": {} } diff --git a/packages/components/src/__builtins__/dayjs.ts b/packages/components/src/__builtins__/dayjs.ts new file mode 100644 index 0000000..e7ae8bd --- /dev/null +++ b/packages/components/src/__builtins__/dayjs.ts @@ -0,0 +1,64 @@ +import { isArr, isFn, isEmpty } from '@formily/shared' +import dayjs, { ConfigType, Dayjs } from 'dayjs' + +export function dayjsable(value: ConfigType, format?: string): Dayjs +export function dayjsable(value: ConfigType[], format?: string): Dayjs[] + +export function dayjsable( + value: ConfigType | ConfigType[], + format?: string +): any { + if (!value) return value + if (Array.isArray(value)) { + return value.map((val) => { + const date = dayjs(val, format) + return date.isValid() ? date : val + }) + } else { + const date = dayjs(value, format) + return date.isValid() ? date : value + } +} + +export const formatDayjsValue = ( + value: any, + format: any, + placeholder?: string +): string | string[] => { + const validFormatDate = (date: any, format: any) => { + if (typeof date === 'number') { + return dayjs(date).format(format) + } + const _date = dayjs(date, format) + return _date.isValid() ? _date.format(format) : date + } + + const formatDate = (date: any, format: any, i = 0) => { + if (!date) return placeholder + if (isArr(format)) { + const _format = format[i] + if (isFn(_format)) { + return _format(date) + } + if (isEmpty(_format)) { + return date + } + return validFormatDate(date, _format) + } else { + if (isFn(format)) { + return format(date) + } + if (isEmpty(format)) { + return date + } + return validFormatDate(date, format) + } + } + if (isArr(value)) { + return value.map((val, index) => { + return formatDate(val, format, index) + }) + } else { + return value ? formatDate(value, format) : value || placeholder + } +} diff --git a/packages/components/src/__builtins__/hooks/index.ts b/packages/components/src/__builtins__/hooks/index.ts index cc3f1e6..331cfc8 100644 --- a/packages/components/src/__builtins__/hooks/index.ts +++ b/packages/components/src/__builtins__/hooks/index.ts @@ -1,2 +1,4 @@ export * from './useClickAway' +export * from './useConfig' export * from './usePrefixCls' +export * from './useToken' diff --git a/packages/components/src/__builtins__/hooks/useConfig.ts b/packages/components/src/__builtins__/hooks/useConfig.ts new file mode 100644 index 0000000..40ebf8e --- /dev/null +++ b/packages/components/src/__builtins__/hooks/useConfig.ts @@ -0,0 +1,5 @@ +import { ConfigProvider } from 'antd' +import { useContext } from 'react' + +const { ConfigContext } = ConfigProvider +export const useConfig = () => useContext(ConfigContext) diff --git a/packages/components/src/__builtins__/hooks/usePrefixCls.ts b/packages/components/src/__builtins__/hooks/usePrefixCls.ts index ff6074a..d8f07ed 100644 --- a/packages/components/src/__builtins__/hooks/usePrefixCls.ts +++ b/packages/components/src/__builtins__/hooks/usePrefixCls.ts @@ -7,6 +7,11 @@ export const usePrefixCls = ( prefixCls?: string } ) => { - const { getPrefixCls } = useContext(ConfigProvider.ConfigContext) - return getPrefixCls(tag, props?.prefixCls) + if ('ConfigContext' in ConfigProvider) { + const { getPrefixCls } = useContext(ConfigProvider.ConfigContext) + return getPrefixCls(tag, props?.prefixCls) + } else { + const prefix = props?.prefixCls ?? 'ant-' + return `${prefix}${tag ?? ''}` + } } diff --git a/packages/components/src/__builtins__/hooks/useToken.ts b/packages/components/src/__builtins__/hooks/useToken.ts new file mode 100644 index 0000000..e5afc35 --- /dev/null +++ b/packages/components/src/__builtins__/hooks/useToken.ts @@ -0,0 +1,3 @@ +import { theme } from 'antd' +const { useToken } = theme +export { useToken } diff --git a/packages/components/src/__builtins__/index.ts b/packages/components/src/__builtins__/index.ts index bf25acb..8a79b27 100644 --- a/packages/components/src/__builtins__/index.ts +++ b/packages/components/src/__builtins__/index.ts @@ -1,5 +1,7 @@ -export * from './moment' +export * from './dayjs' export * from './hooks' -export * from './portal' export * from './loading' export * from './pickDataProps' +export * from './portal' +export * from './sort' +export * from './style' diff --git a/packages/components/src/__builtins__/loading.ts b/packages/components/src/__builtins__/loading.ts index b3a98f3..98bab18 100644 --- a/packages/components/src/__builtins__/loading.ts +++ b/packages/components/src/__builtins__/loading.ts @@ -4,7 +4,7 @@ export const loading = async ( title: React.ReactNode = 'Loading...', processor: () => Promise ) => { - let hide = null + let hide: any = null let loading = setTimeout(() => { hide = message.loading(title) }, 100) diff --git a/packages/components/src/__builtins__/moment.ts b/packages/components/src/__builtins__/moment.ts deleted file mode 100644 index f94c963..0000000 --- a/packages/components/src/__builtins__/moment.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { isArr, isFn, isEmpty } from '@formily/shared' -import moment from 'moment' - -export const momentable = (value: any, format?: string) => { - return Array.isArray(value) - ? value.map((val) => moment(val, format)) - : value - ? moment(value, format) - : value -} - -export const formatMomentValue = ( - value: any, - format: any, - placeholder?: string -): string | string[] => { - const formatDate = (date: any, format: any, i = 0) => { - if (!date) return placeholder - if (isArr(format)) { - const _format = format[i] - if (isFn(_format)) { - return _format(date) - } - if (isEmpty(_format)) { - return date - } - return moment(date).format(_format) - } else { - if (isFn(format)) { - return format(date) - } - if (isEmpty(format)) { - return date - } - return moment(date).format(format) - } - } - if (isArr(value)) { - return value.map((val, index) => { - return formatDate(val, format, index) - }) - } else { - return value ? formatDate(value, format) : value || placeholder - } -} diff --git a/packages/components/src/__builtins__/portal.tsx b/packages/components/src/__builtins__/portal.tsx index 2ae7046..a1ea987 100644 --- a/packages/components/src/__builtins__/portal.tsx +++ b/packages/components/src/__builtins__/portal.tsx @@ -1,7 +1,8 @@ -import React, { Fragment } from 'react' -import ReactDOM, { createPortal } from 'react-dom' +import { Observer, ReactFC } from '@formily/react' import { observable } from '@formily/reactive' -import { Observer } from '@formily/react' +import React, { Fragment } from 'react' +import { createPortal } from 'react-dom' +import { render as reactRender, unmount as reactUnmount } from './render' export interface IPortalProps { id?: string | symbol } @@ -9,7 +10,7 @@ export interface IPortalProps { const PortalMap = observable(new Map()) export const createPortalProvider = (id: string | symbol) => { - const Portal = (props: React.PropsWithChildren) => { + const Portal: ReactFC = (props) => { if (props.id && !PortalMap.has(props.id)) { PortalMap.set(props.id, null) } @@ -19,10 +20,10 @@ export const createPortalProvider = (id: string | symbol) => { {props.children} {() => { - if (!props.id) return null + if (!props.id) return <> const portal = PortalMap.get(props.id) if (portal) return createPortal(portal, document.body) - return null + return <> }} @@ -42,7 +43,7 @@ export function createPortalRoot( if (PortalMap.has(id)) { PortalMap.set(id, renderer?.()) } else if (host) { - ReactDOM.render({renderer?.()}, host) + reactRender({renderer?.()}, host) } } @@ -51,8 +52,10 @@ export function createPortalRoot( PortalMap.set(id, null) } if (host) { - ReactDOM.unmountComponentAtNode(host) - host.parentNode?.removeChild(host) + const unmountResult = reactUnmount(host) + if (unmountResult && host.parentNode) { + host.parentNode?.removeChild(host) + } } } diff --git a/packages/components/src/__builtins__/render.ts b/packages/components/src/__builtins__/render.ts new file mode 100644 index 0000000..0cfbe89 --- /dev/null +++ b/packages/components/src/__builtins__/render.ts @@ -0,0 +1,90 @@ +import { ReactElement } from 'react' +import * as ReactDOM from 'react-dom' +import type { Root } from 'react-dom/client' + +// 移植自rc-util: https://github.com/react-component/util/blob/master/src/React/render.ts + +type CreateRoot = (container: ContainerType) => Root + +// Let compiler not to search module usage +const fullClone = { + ...ReactDOM, +} as typeof ReactDOM & { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?: { + usingClientEntryPoint?: boolean + } + createRoot?: CreateRoot +} + +const { version, render: reactRender, unmountComponentAtNode } = fullClone + +let createRoot: CreateRoot +try { + const mainVersion = Number((version || '').split('.')[0]) + if (mainVersion >= 18 && fullClone.createRoot) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + createRoot = fullClone.createRoot + } +} catch (e) { + // Do nothing; +} + +function toggleWarning(skip: boolean) { + const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = fullClone + + if ( + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED && + typeof __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === 'object' + ) { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint = + skip + } +} + +const MARK = '__antd_mobile_root__' + +// ========================== Render ========================== +type ContainerType = (Element | DocumentFragment) & { + [MARK]?: Root +} + +function legacyRender(node: ReactElement, container: ContainerType) { + reactRender(node, container) +} + +function concurrentRender(node: ReactElement, container: ContainerType) { + toggleWarning(true) + const root = container[MARK] || createRoot(container) + toggleWarning(false) + root.render(node) + container[MARK] = root +} + +export function render(node: ReactElement, container: ContainerType) { + if (createRoot as unknown) { + concurrentRender(node, container) + return + } + legacyRender(node, container) +} + +// ========================== Unmount ========================= +function legacyUnmount(container: ContainerType) { + return unmountComponentAtNode(container) +} + +async function concurrentUnmount(container: ContainerType) { + // Delay to unmount to avoid React 18 sync warning + return Promise.resolve().then(() => { + container[MARK]?.unmount() + delete container[MARK] + }) +} + +export function unmount(container: ContainerType) { + if (createRoot as unknown) { + return concurrentUnmount(container) + } + + return legacyUnmount(container) +} diff --git a/packages/components/src/__builtins__/sort.tsx b/packages/components/src/__builtins__/sort.tsx new file mode 100644 index 0000000..c0936d1 --- /dev/null +++ b/packages/components/src/__builtins__/sort.tsx @@ -0,0 +1,110 @@ +import { DndContext, DragEndEvent, DragStartEvent } from '@dnd-kit/core' +import { SortableContext, useSortable } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { ReactFC } from '@formily/reactive-react' +import React, { createContext, useContext } from 'react' + +export interface ISortableContainerProps { + list: any[] + start?: number + accessibility?: { + container?: Element + } + onSortStart?: (event: DragStartEvent) => void + onSortEnd?: (event: { oldIndex: number; newIndex: number }) => void +} + +export function SortableContainer>( + Component: ReactFC +): ReactFC { + return ({ + list, + start = 0, + accessibility, + onSortStart, + onSortEnd, + ...props + }) => { + const _onSortEnd = (event: DragEndEvent) => { + const { active, over } = event + const oldIndex = (active.id as number) - 1 + const newIndex = (over?.id as number) - 1 + onSortEnd?.({ + oldIndex, + newIndex, + }) + } + + return ( + + index + start + 1)}> + {props.children} + + + ) + } +} + +export const useSortableItem = () => { + return useContext(SortableItemContext) +} + +export const SortableItemContext = createContext< + Partial> +>({}) + +export interface ISortableElementProps { + index?: number + lockAxis?: 'x' | 'y' +} + +export function SortableElement>( + Component: ReactFC +): ReactFC { + return ({ index = 0, lockAxis, ...props }) => { + const sortable = useSortable({ + id: index + 1, + }) + const { setNodeRef, transform } = sortable + if (transform) { + switch (lockAxis) { + case 'x': + transform.y = 0 + break + case 'y': + transform.x = 0 + break + + default: + break + } + } + const style = { + ...props.style, + transform: CSS.Transform.toString(transform), + } + + return ( + + {Component({ + ...props, + style, + ref: setNodeRef, + } as unknown as T)} + + ) + } +} + +export function SortableHandle>( + Component: ReactFC +): ReactFC { + return (props: T) => { + const { attributes, listeners } = useSortableItem() + return + } +} diff --git a/packages/components/src/__builtins__/style.ts b/packages/components/src/__builtins__/style.ts new file mode 100644 index 0000000..4f36279 --- /dev/null +++ b/packages/components/src/__builtins__/style.ts @@ -0,0 +1,105 @@ +import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs' +import { useStyleRegister } from '@ant-design/cssinjs' +import { merge } from '@formily/shared' +import type { ComponentTokenMap, GlobalToken } from 'antd/es/theme/interface' +import { useConfig, useToken } from './hooks' + +export type OverrideComponent = keyof ComponentTokenMap | (string & {}) + +export interface StyleInfo { + hashId: string + prefixCls: string + rootPrefixCls: string + iconPrefixCls: string +} + +export type TokenWithCommonCls = T & { + /** Wrap component class with `.` prefix */ + componentCls: string + /** Origin prefix which do not have `.` prefix */ + prefixCls: string + /** Wrap icon class with `.` prefix */ + iconCls: string + /** Wrap ant prefixCls class with `.` prefix */ + antCls: string +} + +export type GenerateStyle< + ComponentToken extends object = TokenWithCommonCls, + ReturnType = CSSInterpolation +> = (token: ComponentToken, options?: any) => ReturnType + +export const genCommonStyle = ( + token: any, + componentPrefixCls: string +): CSSObject => { + const { fontFamily, fontSize } = token + + const rootPrefixSelector = `[class^="${componentPrefixCls}"], [class*=" ${componentPrefixCls}"]` + + return { + [rootPrefixSelector]: { + fontFamily, + fontSize, + boxSizing: 'border-box', + + '&::before, &::after': { + boxSizing: 'border-box', + }, + + [rootPrefixSelector]: { + boxSizing: 'border-box', + + '&::before, &::after': { + boxSizing: 'border-box', + }, + }, + }, + } +} +export type UseComponentStyleResult = [ + (node: React.ReactNode) => React.ReactElement, + string +] + +export const genStyleHook = ( + component: ComponentName, + styleFn: ( + token: TokenWithCommonCls, + info: StyleInfo + ) => CSSInterpolation +) => { + return (prefixCls: string): UseComponentStyleResult => { + const { theme, token, hashId } = useToken() + const { getPrefixCls, iconPrefixCls } = useConfig() + const rootPrefixCls = getPrefixCls() + return [ + useStyleRegister( + { + theme, + token, + hashId, + path: ['formily-antd', component, prefixCls, iconPrefixCls], + }, + () => { + const componentCls = `.${prefixCls}` + const mergedToken: TokenWithCommonCls = merge(token, { + componentCls, + prefixCls, + iconCls: `.${iconPrefixCls}`, + antCls: `.${rootPrefixCls}`, + }) + + const styleInterpolation = styleFn(mergedToken, { + hashId, + prefixCls, + rootPrefixCls, + iconPrefixCls, + }) + return [genCommonStyle(token, prefixCls), styleInterpolation] + } + ), + hashId, + ] + } +} diff --git a/packages/components/src/__tests__/dayjs.spec.ts b/packages/components/src/__tests__/dayjs.spec.ts new file mode 100644 index 0000000..b8a4283 --- /dev/null +++ b/packages/components/src/__tests__/dayjs.spec.ts @@ -0,0 +1,77 @@ +import dayjs from 'dayjs' +import { formatDayjsValue, dayjsable } from '../__builtins__/dayjs' + +test('dayjsable is usable', () => { + expect(dayjs.isDayjs(dayjsable('2021-09-08'))).toBe(true) + expect(dayjs.isDayjs(dayjsable('12:11'))).toBe(false) + expect(dayjs.isDayjs(dayjsable(''))).toBe(false) + expect( + dayjsable(['2021-09-08', '2021-12-29']).every((item) => dayjs.isDayjs(item)) + ).toBe(true) + expect( + dayjsable(['12:11', '2021-12-29']).every((item) => dayjs.isDayjs(item)) + ).toBe(false) +}) + +test('formatDayjsValue is usable', () => { + expect(formatDayjsValue('', 'YYYY-MM-DD', '~')).toBe('~') + expect(formatDayjsValue([''], 'YYYY-MM-DD', '~')).toEqual(['~']) + expect(formatDayjsValue(['', '12:11'], 'YYYY-MM-DD', '~')).toEqual([ + '~', + '12:11', + ]) + + expect(formatDayjsValue('2021-12-21 15:47:00', 'YYYY-MM-DD')).toBe( + '2021-12-21' + ) + expect(formatDayjsValue('2021-12-21 15:47:00', undefined)).toBe( + '2021-12-21 15:47:00' + ) + expect(formatDayjsValue('2021-12-21 15:47:00', (date: string) => date)).toBe( + '2021-12-21 15:47:00' + ) + expect(formatDayjsValue('12:11', 'HH:mm')).toBe('12:11') + expect(formatDayjsValue('12:11:11', 'HH:mm:ss')).toBe('12:11:11') + expect(formatDayjsValue(['12:11'], ['HH:mm'])).toEqual(['12:11']) + expect(formatDayjsValue(['12:11:11'], ['HH:mm:ss'])).toEqual(['12:11:11']) + expect(formatDayjsValue(1663155911097, 'YYYY-MM-DD HH:mm:ss')).toBe( + dayjs(1663155911097).format('YYYY-MM-DD HH:mm:ss') + ) + expect(formatDayjsValue([1663155911097], ['YYYY-MM-DD HH:mm:ss'])).toEqual([ + dayjs(1663155911097).format('YYYY-MM-DD HH:mm:ss'), + ]) + expect( + formatDayjsValue('2022-09-15T09:56:26.000Z', 'YYYY-MM-DD HH:mm:ss') + ).toBe(dayjs('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss')) + expect( + formatDayjsValue(['2022-09-15T09:56:26.000Z'], ['YYYY-MM-DD HH:mm:ss']) + ).toEqual([dayjs('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss')]) + expect(formatDayjsValue('2022-09-15 09:56:26', 'HH:mm:ss')).toBe('09:56:26') + expect(formatDayjsValue(['2022-09-15 09:56:26'], ['HH:mm:ss'])).toEqual([ + '09:56:26', + ]) + expect( + formatDayjsValue( + ['2021-12-21 15:47:00', '2021-12-29 15:47:00'], + 'YYYY-MM-DD' + ) + ).toEqual(['2021-12-21', '2021-12-29']) + expect( + formatDayjsValue( + ['2021-12-21 16:47:00', '2021-12-29 18:47:00'], + (date: string) => date + ) + ).toEqual(['2021-12-21 16:47:00', '2021-12-29 18:47:00']) + expect( + formatDayjsValue( + ['2021-12-21 16:47:00', '2021-12-29 18:47:00'], + ['YYYY-MM-DD', (date: string) => date] + ) + ).toEqual(['2021-12-21', '2021-12-29 18:47:00']) + expect( + formatDayjsValue( + ['2021-12-21 16:47:00', '2021-12-29 18:47:00'], + ['YYYY-MM-DD', undefined] + ) + ).toEqual(['2021-12-21', '2021-12-29 18:47:00']) +}) diff --git a/packages/components/src/array-base/index.tsx b/packages/components/src/array-base/index.tsx index ef5d00c..1ec27fe 100644 --- a/packages/components/src/array-base/index.tsx +++ b/packages/components/src/array-base/index.tsx @@ -1,26 +1,27 @@ -import React, { createContext, useContext } from 'react' -import { Button } from 'antd' import { + CopyOutlined, DeleteOutlined, DownOutlined, - UpOutlined, - PlusOutlined, MenuOutlined, + PlusOutlined, + UpOutlined, } from '@ant-design/icons' import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon' -import { ButtonProps } from 'antd/lib/button' import { ArrayField } from '@formily/core' import { + ReactFC, + RecordScope, + RecordsScope, + Schema, useField, useFieldSchema, - Schema, - JSXComponent, - ExpressionScope, } from '@formily/react' -import { isValid, clone, isBool } from '@formily/shared' -import { SortableHandle } from 'react-sortable-hoc' -import { usePrefixCls } from '../__builtins__' +import { clone, isValid } from '@formily/shared' +import { Button, ButtonProps } from 'antd' import cls from 'classnames' +import React, { createContext, forwardRef, useContext } from 'react' +import { SortableHandle, usePrefixCls } from '../__builtins__' +import useStyle from './style' export interface IArrayBaseAdditionProps extends ButtonProps { title?: string @@ -36,38 +37,41 @@ export interface IArrayBaseContext { export interface IArrayBaseItemProps { index: number - record: any + record: ((index: number) => Record) | Record +} + +type CommonProps = AntdIconProps & { + index?: number } export type ArrayBaseMixins = { - Addition?: React.FC - Remove?: React.FC - MoveUp?: React.FC - MoveDown?: React.FC - SortHandle?: React.FC - Index?: React.FC - useArray?: () => IArrayBaseContext - useIndex?: () => number - useRecord?: () => any + Addition: ReactFC + Copy: ReactFC + Remove: ReactFC + MoveUp: ReactFC + MoveDown: React.FC> + SortHandle: ReactFC + Index: React.FC + useArray: () => IArrayBaseContext | null + useIndex: (index?: number) => number + useRecord: (record?: number) => any } export interface IArrayBaseProps { disabled?: boolean onAdd?: (index: number) => void + onCopy?: (index: number) => void onRemove?: (index: number) => void onMoveDown?: (index: number) => void onMoveUp?: (index: number) => void } -type ComposedArrayBase = React.FC & - ArrayBaseMixins & { - Item?: React.FC - mixin?: (target: T) => T & ArrayBaseMixins - } +const ArrayBaseContext = createContext(null) -const ArrayBaseContext = createContext(null) +const ItemContext = createContext(null) -const ItemContext = createContext(null) +const takeRecord = (val: any, index?: number) => + typeof val === 'function' ? val(index) : val const useArray = () => { return useContext(ArrayBaseContext) @@ -75,93 +79,105 @@ const useArray = () => { const useIndex = (index?: number) => { const ctx = useContext(ItemContext) - return ctx ? ctx.index : index + return (ctx ? ctx.index : index) || 0 } const useRecord = (record?: number) => { const ctx = useContext(ItemContext) - return ctx ? ctx.record : record + return takeRecord(ctx ? ctx.record : record, ctx?.index) +} + +const getSchemaDefaultValue = (schema?: Schema) => { + if (schema?.type === 'array') return [] + if (schema?.type === 'object') return {} + if (schema?.type === 'void') { + for (let key in schema.properties) { + const value = getSchemaDefaultValue(schema.properties[key]) + if (isValid(value)) return value + } + } } const getDefaultValue = (defaultValue: any, schema: Schema) => { if (isValid(defaultValue)) return clone(defaultValue) if (Array.isArray(schema?.items)) - return getDefaultValue(defaultValue, schema.items[0]) - if (schema?.items?.type === 'array') return [] - if (schema?.items?.type === 'boolean') return true - if (schema?.items?.type === 'date') return '' - if (schema?.items?.type === 'datetime') return '' - if (schema?.items?.type === 'number') return 0 - if (schema?.items?.type === 'object') return {} - if (schema?.items?.type === 'string') return '' - return null + return getSchemaDefaultValue(schema?.items[0]) + return getSchemaDefaultValue(schema?.items) } -export const ArrayBase: ComposedArrayBase = (props) => { +const InternalArrayBase: ReactFC = (props) => { const field = useField() const schema = useFieldSchema() return ( - - {props.children} - + field.value}> + + {props.children} + + ) } -ArrayBase.Item = ({ children, ...props }) => { +const Item: ReactFC = ({ children, ...props }) => { return ( - + props.index} + getRecord={() => takeRecord(props.record, props.index)} + > {children} - + ) } -const SortHandle = SortableHandle((props: any) => { +const InternalSortHandle = SortableHandle((props) => { const prefixCls = usePrefixCls('formily-array-base') - return ( + const [wrapSSR, hashId] = useStyle(prefixCls) + return wrapSSR( ) -}) as any +}) -ArrayBase.SortHandle = (props) => { +const SortHandle: ReactFC = (props) => { const array = useArray() if (!array) return null if (array.field?.pattern !== 'editable') return null - return + return } -ArrayBase.Index = (props) => { +const Index: React.FC> = (props) => { const index = useIndex() const prefixCls = usePrefixCls('formily-array-base') - return ( - - #{index + 1}. + const [wrapSSR, hashId] = useStyle(prefixCls) + return wrapSSR( + + #{(index || 0) + 1}. ) } -ArrayBase.Addition = (props) => { +const Addition: ReactFC = (props) => { const self = useField() const array = useArray() const prefixCls = usePrefixCls('formily-array-base') + const [wrapSSR, hashId] = useStyle(prefixCls) if (!array) return null if ( array.field?.pattern !== 'editable' && array.field?.pattern !== 'disabled' ) return null - return ( + return wrapSSR(